Android: как повернуть растровое изображение в центральной точке - PullRequest
82 голосов
/ 12 ноября 2010

Я целый день искал решение этой проблемы, но ничего не помогло, даже ответы здесь. Документация тоже ничего не объясняет.

Я просто пытаюсь добиться поворота в направлении другого объекта. Проблема в том, что растровое изображение вращается не вокруг фиксированной точки, а вокруг растровых изображений (0,0).

Вот код, с которым у меня проблемы:

  Matrix mtx = new Matrix();
  mtx.reset();
  mtx.preTranslate(-centerX, -centerY);
  mtx.setRotate((float)direction, -centerX, -centerY);
  mtx.postTranslate(pivotX, pivotY);
  Bitmap rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0, spriteWidth, spriteHeight, mtx, true);
  this.bitmap = rotatedBMP;

Странная часть, не имеет значения, как я изменяю значения в pre / postTranslate() и аргументы с плавающей точкой в ​​setRotation(). Может кто-нибудь помочь и подтолкнуть меня в правильном направлении? :)

Ответы [ 8 ]

100 голосов
/ 29 ноября 2010

Я надеюсь, что следующая последовательность кода поможет вам:

Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight, config);
Canvas canvas = new Canvas(targetBitmap);
Matrix matrix = new Matrix();
matrix.setRotate(mRotation,source.getWidth()/2,source.getHeight()/2);
canvas.drawBitmap(source, matrix, new Paint());

Если вы проверите следующий метод из ~frameworks\base\graphics\java\android\graphics\Bitmap.java

public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
        Matrix m, boolean filter)

это объясняет, что он делает с вращением и переводит.

77 голосов
/ 25 апреля 2013

Отредактировано : оптимизированный код.

public static Bitmap RotateBitmap(Bitmap source, float angle)
{
      Matrix matrix = new Matrix();
      matrix.postRotate(angle);
      return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}

Чтобы получить растровое изображение из ресурсов:

Bitmap source = BitmapFactory.decodeResource(this.getResources(), R.drawable.your_img);
25 голосов
/ 11 декабря 2010

Я вернулся к этой проблеме сейчас, когда мы дорабатываем игру, и я просто решил опубликовать, что сработало для меня.

Это метод вращения Матрицы:

this.matrix.reset();
this.matrix.setTranslate(this.floatXpos, this.floatYpos);
this.matrix.postRotate((float)this.direction, this.getCenterX(), this.getCenterY()); 

(this.getCenterX() - это в основном позиция X растровых изображений + ширина растровых изображений / 2)

И метод рисования растрового изображения (вызывается через класс RenderManager):

canvas.drawBitmap(this.bitmap, this.matrix, null);

Так что это довольно просто, но я нахожу странным, что я не смог заставить его работать до setRotate, за которым следует postTranslate.Может быть, кто-то знает, почему это не работает?Теперь все растровые изображения вращаются правильно, но не без незначительного снижения качества растрового изображения: /

В любом случае, спасибо за вашу помощь!

7 голосов
/ 30 ноября 2010

Вы также можете повернуть ImageView, используя RotateAnimation:

RotateAnimation rotateAnimation = new RotateAnimation(from, to,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
rotateAnimation.setInterpolator(new LinearInterpolator());
rotateAnimation.setDuration(ANIMATION_DURATION);
rotateAnimation.setFillAfter(true);

imageView.startAnimation(rotateAnimation);
5 голосов
/ 04 декабря 2010

Вы можете использовать что-то вроде следующего:

<code>
Matrix matrix = new Matrix();
matrix.setRotate(mRotation,source.getWidth()/2,source.getHeight()/2);
RectF rectF = new RectF(0, 0, source.getWidth(), source.getHeight());
matrix.mapRect(rectF);
Bitmap targetBitmap = Bitmap.createBitmap(rectF.width(), rectF.height(), config);
Canvas canvas = new Canvas(targetBitmap);
canvas.drawBitmap(source, matrix, new Paint());
1 голос
/ 31 октября 2012

Я использовал эти конфигурации и все еще имею проблему пикселизации:

Bitmap bmpOriginal = BitmapFactory.decodeResource(this.getResources(), R.drawable.map_pin);
        Bitmap targetBitmap = Bitmap.createBitmap((bmpOriginal.getWidth()),
                (bmpOriginal.getHeight()), 
                Bitmap.Config.ARGB_8888);
        Paint p = new Paint();
        p.setAntiAlias(true);

        Matrix matrix = new Matrix();       
        matrix.setRotate((float) lock.getDirection(),(float) (bmpOriginal.getWidth()/2),
                (float)(bmpOriginal.getHeight()/2));

        RectF rectF = new RectF(0, 0, bmpOriginal.getWidth(), bmpOriginal.getHeight());
        matrix.mapRect(rectF);

        targetBitmap = Bitmap.createBitmap((int)rectF.width(), (int)rectF.height(), Bitmap.Config.ARGB_8888);


        Canvas tempCanvas = new Canvas(targetBitmap); 
        tempCanvas.drawBitmap(bmpOriginal, matrix, p);
1 голос
/ 05 декабря 2010

Посмотрите на образец из Google под названием Lunar Lander, изображение корабля там поворачивается динамически.

Пример кода Lunar Lander

0 голосов
/ 07 октября 2013
matrix.reset();
matrix.setTranslate( anchor.x, anchor.y );
matrix.postRotate((float) rotation , 0,0);
matrix.postTranslate(positionOfAnchor.x, positionOfAnchor.x);
c.drawBitmap(bitmap, matrix, null); 
...