Позиционирование и настройка Android canvas

#android #canvas #android-vectordrawable

#Android #canvas #android-векторное отображение

Вопрос:

Итак, это мой сценарий:

  • У меня есть svg-изображение, которое содержит все музыкальные ноты в staff (что-то вроде листа спрайтов)
  • У меня есть два svg-изображения, которые содержат ключ (возможно, я все равно смогу объединить их вместе)

Все они преобразуются в векторные изображения для Android.

Что я хочу сделать, так это выбрать заметку из первого svg, выбрать ключ, а затем показать их рядом друг с другом (два изображения должны быть выровнены).

Итак, чего мне удалось добиться, так это выбрать часть svg для заметки (мне нужно уточнить размер прямоугольника). Но у меня все еще возникает проблема с отображением их обоих в одной строке.

 public MusicScore(Context context) {
        super(context);
        paint = new Paint();
        paint.setColor(Color.BLACK);
        Resources res = context.getResources();
        musicClef = (VectorDrawable) res.getDrawable(R.drawable.ic_bassclef, null);
        musicNotes = (VectorDrawable) res.getDrawable(R.drawable.ic_musicnotes, null);
        int width = getWidth();
        int height = getHeight();
        Log.i("MUSIC", "H: "   musicClef.getMinimumHeight()   " W: "   musicClef.getMinimumWidth());
    }

    @Override
    protected void onDraw(Canvas canvas){
        Log.i("MUSIC", "Called");
        int left = getWidth()/2;
        int top = getHeight()/2;
        musicClef.setBounds(0,0,musicClef.getIntrinsicWidth(), musicClef.getIntrinsicHeight()   );

        Bitmap source = Bitmap.createBitmap(musicNotes.getIntrinsicWidth(), musicNotes.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Bitmap clefSource = Bitmap.createBitmap(musicClef.getIntrinsicWidth(), musicClef.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas newcanvas = new Canvas(source);
        Canvas clefCanvas = new Canvas(clefSource);
        int notesLeft = musicClef.getIntrinsicWidth();
        int notesTop = musicClef.getIntrinsicHeight();
        musicNotes.setBounds(0, 0, musicNotes.getIntrinsicWidth(), musicNotes.getIntrinsicHeight());
        musicNotes.draw(newcanvas);
        musicClef.draw(clefCanvas);
        Rect rect = new Rect(1150,0,1700, musicNotes.getIntrinsicHeight());
        Rect rect2 = new Rect(notesLeft ,0, notesLeft   450, musicNotes.getIntrinsicHeight());
        Rect clefRect = new Rect(0, 0, musicClef.getIntrinsicWidth(), musicClef.getIntrinsicHeight());

        canvas.drawBitmap(clefSource, null, clefRect, null);
        canvas.drawBitmap(source, rect, rect2, null);

    }
  

Итак, с помощью этого кода я могу показать часть заметок, которую можно нарисовать, после преобразования ее в растровое изображение. И я также могу нарисовать их оба, и горизонтальное положение выровнено. Проблема в том, что вертикальное положение не выровнено, что я получаю:

текущий вывод

Итак, я знаю, что мой код неверен (я довольно новичок в canvas на Android и пытаюсь понять, что делать), и то, что я узнал до сих пор, это:

  • для того, чтобы выбрать часть изображения, мне нужно преобразовать его в растровое изображение (я не нашел способа сделать это напрямую с помощью VectorDrawable)
  • При рисовании растрового изображения на холсте с помощью drawBitmap первый прямоугольник представляет область участка, которую я хочу показать, а второй — размер и положение отображаемой области.
  • Для отображения растрового изображения на холсте мне нужно создать холст из растрового изображения и нарисовать его на нем, чтобы оно отображалось. Это правильно?

Итак, у меня есть несколько вопросов:

  • Я хотел бы понять, как выровнять изображения по вертикали, чтобы они начинались с одного и того же y (сверху).
  • Я не уверен, что векторное изображение — лучшая идея, может быть, лучше преобразовать его в png, зависящие от отображения? Или в любом случае размер холста зависит от экрана? Или, может быть, мне нужно сделать мой код независимым от экрана (я полагаю, что getIntrinsicWidth / Height возвращают реальный размер изображения, поэтому, возможно, мне нужно его масштабировать?)
  • Почему мне нужно явно устанавливать границы обоих изображений, чтобы они отображались?

ОБНОВЛЕНИЕ # 1

Итак, я понял, почему, вероятно, мои изображения не выровнены по одной строке. Похоже, что при создании векторного ресурса по какой-то причине размеры «адаптируются», не уверен, что это делают системы Android или Android studio. Но в любом случае, что я обнаружил после загрузки двух изображений с одинаковой высотой в пикселях, так это то, что для одного у меня есть высота, а для другого у меня другая высота (почти вдвое больше), и это объясняет, почему изображение сдвинуто снизу.

Итак, что я попытался, так это создать единое изображение с обоими примечаниями и ключами к ним, и это вроде как работает в эмуляторе. Но при тестировании на реальном устройстве я получаю ошибку:

Без OpenGLRenderer: Растровое изображение слишком большого размера для загрузки в текстуру (11732×1168, max = 8192×8192) Растровое изображение слишком большого размера для загрузки в текстуру (11732×1168, max = 8192×8192)

я могу понять, что означает ошибка, но в любом случае размер изображения в пикселях равен: 2933×292 пикселей. Почему getIntrinsicWidth и getIntrinsicHeight возвращают эти размеры? каковы их показатели?

Мне интересно, что, возможно, векторная графика — не лучший выбор? Может быть, лучше преобразовать его в png, зависящие от экрана? и использовать их?