#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, зависящие от экрана? и использовать их?