#android #bitmap #rotation
#Android #растровое изображение #вращение
Вопрос:
У меня возникла проблема с правильным вращением растрового изображения. У меня есть SurfaceView с несколькими растровыми изображениями на нем. Эти растровые изображения существуют в arraylist и, используя цикл for, я вызываю canvas.drawBitmap для каждого из них в методе onDraw.
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
for (int i = 0; i < jumper.size(); i ) {
canvas.drawBitmap(jumper.get(i).getGraphic(), jumper.get(i)
.getCoordinates().getX(), jumper.get(i).getCoordinates()
.getY(), null);
}
}
Я пытаюсь заставить пользователя выбрать конкретное растровое изображение (одно из многих), а затем повернуть это растровое изображение, пока пользователь проводит пальцем по экрану. Итак, вот код поворота. На данный момент я просто использую значок Android по умолчанию (72x72px), существующий в случайном месте где-то около центра экрана.
private void rotateJumper(int direction) {
Matrix matrix = new Matrix();
Bitmap source = jumper.get(selectedJumperPos).getGraphic();
matrix.postRotate(direction, source.getWidth() / 2,
source.getHeight() / 2);
int x = 0;
int y = 0;
int width = 72;
int height = 72;
Bitmap tempBitmap = Bitmap.createBitmap(source, x, y, width, height,
matrix, true);
jumper.get(selectedJumperPos).setGraphic(tempBitmap);
}
Целочисленное направление равно 1 или -1 в зависимости от направления перетаскивания пальцем. Таким образом, изображение должно поворачиваться на 1 градус для каждого события движения.Событие ACTION_MOVE.
Вот проблемы:
- Изображение не вращается вокруг центра изображения. Центр вращения CW находится в нижнем левом углу. Центр вращения CCW находится в правом верхнем углу.
- Поскольку оно не вращается вокруг центра, изображение выходит за свои первоначальные границы и в конечном итоге исчезает.
- Изображение становится размытым при вращении.
Я был бы признателен за любую помощь, которую вы могли бы мне оказать.
Спасибо!
Ответ №1:
Используйте матрицу, чтобы нарисовать существующее растровое изображение на холсте, а не создавать новое растровое изображение:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
for (int i = 0; i < jumper.size(); i ) {
canvas.drawBitmap(jumper.get(i).getGraphic(), jumper.get(i).getMatrix(), null);
}
}
private void rotateJumper(int direction) {
Matrix matrix = jumper.get(selectedJumperPos).getMatrix();
if(matrix == null) {
matrix = new Matrix();
matrix.setTranslate(jumper.get(...).getCoord...().getX(), jumper.get(..).getCoord...().getY());
jumper.get(selectedJumperPos).setMatrix(matrix);
}
Bitmap source = jumper.get(selectedJumperPos).getGraphic();
matrix.postRotate(direction, source.getWidth() / 2,
source.getHeight() / 2);
}
Комментарии:
1. Это сработало. Потребовался довольно большой редизайн, но это сработало. Спасибо!
2. Вместо того, чтобы создавать новое растровое изображение каждый раз, когда происходит поворот, матрица сохраняется и используется во время рендеринга. В rotateJumper мы инициализируем матрицу только в случае необходимости, затем поворачиваем ее вокруг центра растрового изображения. Мы используем матрицу в методе onDraw при рисовании растрового изображения — матрица может включать данные о том, где его рисовать на холсте (перевод), насколько большим его рисовать (масштаб) и его вращение.
Ответ №2:
Простите меня за довольно оффтопичный ответ, но ваш цикл for привлек мое внимание. Возможно, было бы возможно записать его в «более читаемом» формате;
for (YourJumperItem item : jumper) {
canvas.drawBitmap(
item.getGraphic(), item.getCoordinates().getX(),
item.getCoordinates().getY(), null );
}
Где YourJumperItem
— тип класса, содержащийся в вашем массиве перемычек. К сожалению, не могу много сказать о вращении растровых изображений, я просто продвигаю этот удобный способ написания циклов for.