web-dev-qa-db-de.com

Android: So drehen Sie eine Bitmap auf einem Mittelpunkt

Ich habe über einen Tag nach einer Lösung für dieses Problem gesucht, aber nichts hilft, selbst die Antworten hier. Dokumentation erklärt auch nichts.

Ich versuche einfach, eine Drehung in Richtung eines anderen Objekts zu bekommen. Das Problem ist, dass die Bitmap nicht um einen festen Punkt gedreht wird, sondern um die Bitmaps (0,0).

Hier ist der Code, mit dem ich Probleme habe:

  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;

Der seltsame Teil ist, dass es keine Rolle spielt, wie ich die Werte in pre/postTranslate() und die float-Argumente in setRotation() ändere. Kann mir bitte jemand helfen und mich in die richtige Richtung schieben? :)

82
Stefan

Ich hoffe, die folgende Sequenz von Code wird Ihnen helfen:

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());

Wenn Sie die folgende Methode mit ~frameworks\base\graphics\Java\Android\graphics\Bitmap.Java Überprüfen

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

dies würde erklären, was es mit Rotation und Übersetzen macht.

100
Sudar Nimalan

Bearbeitet: optimierter Code.

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);
}

So beziehen Sie Bitmap aus Ressourcen:

Bitmap source = BitmapFactory.decodeResource(this.getResources(), R.drawable.your_img);
77
Arvis

Ich bin auf dieses Problem zurückgekommen, nachdem wir das Spiel fertiggestellt haben, und habe mir nur überlegt, was für mich funktioniert.

Dies ist die Methode zum Drehen der Matrix:

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

(this.getCenterX() ist im Grunde die Bitmaps-X-Position + die Bitmaps-Breite/2)

Und die Methode zum Zeichnen der Bitmap (über eine RenderManager -Klasse aufgerufen):

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

Es ist also ziemlich einfach, aber ich finde es merkwürdig, dass ich es nicht zum Laufen bringen konnte, indem setRotate gefolgt von postTranslate. Vielleicht weiß jemand, warum das nicht funktioniert? Jetzt drehen sich alle Bitmaps richtig, aber es kommt nicht zu einer geringfügigen Verschlechterung der Bitmap-Qualität: /

Trotzdem vielen Dank für Ihre Hilfe!

25
Ste

Sie können das ImageView auch mit einem RotateAnimation drehen:

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);
7
Macarse

Sie können Folgendes verwenden:


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());
5
Sudar Nimalan

Schauen Sie sich das Beispiel von Google namens Lunar Lander an, das Schiffsbild dort wird dynamisch gedreht.

Lunar Lander Codebeispiel

1
sprite

Ich habe diese Konfigurationen verwendet und habe immer noch das Problem der Pixelisierung:

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
MSaudi
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); 
0
Louie Almeda