Проблема с вращением растрового изображения в Android

#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.

Вот проблемы:

  1. Изображение не вращается вокруг центра изображения. Центр вращения CW находится в нижнем левом углу. Центр вращения CCW находится в правом верхнем углу.
  2. Поскольку оно не вращается вокруг центра, изображение выходит за свои первоначальные границы и в конечном итоге исчезает.
  3. Изображение становится размытым при вращении.

Я был бы признателен за любую помощь, которую вы могли бы мне оказать.

Спасибо!

Ответ №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.