Android:如何在中心点上旋转位图

Android:如何在中心点上旋转位图,android,matrix,bitmap,center,image-rotation,Android,Matrix,Bitmap,Center,Image Rotation,我花了一天多的时间寻找这个问题的解决方案,但没有任何帮助,即使是这里的答案。文档并不能解释任何事情 我只是想得到另一个物体的旋转方向。问题在于位图不是围绕固定点旋转,而是围绕位图(0,0)旋转 以下是我遇到问题的代码: Matrix mtx = new Matrix(); mtx.reset(); mtx.preTranslate(-centerX, -centerY); mtx.setRotate((float)direction, -centerX, -centerY);

我花了一天多的时间寻找这个问题的解决方案,但没有任何帮助,即使是这里的答案。文档并不能解释任何事情

我只是想得到另一个物体的旋转方向。问题在于位图不是围绕固定点旋转,而是围绕位图(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()中的浮点参数都无关紧要。有人能帮我,把我推向正确的方向吗?:)

我希望以下代码序列将对您有所帮助:

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)

这将解释它对旋转和平移的作用。

您也可以使用
RotateAnimation
旋转
ImageView

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

您可以使用以下内容:

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

矩阵=新矩阵();
matrix.setRotate(mRotation,source.getWidth()/2,source.getHeight()/2);
RectF RectF=new RectF(0,0,source.getWidth(),source.getHeight());
matrix.mapRect(rectF);
位图targetBitmap=Bitmap.createBitmap(rectF.width(),rectF.height(),config);
画布画布=新画布(targetBitmap);
drawBitmap(源、矩阵、新绘制());

看看谷歌的月球着陆器样本,那里的飞船图像是动态旋转的


现在我们正在完成游戏,我又回到了这个问题上,我只是想发布对我有用的东西

这是旋转矩阵的方法:

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
后跟
post translate
使其工作。也许有人知道为什么这样不行?现在,所有位图都可以正常旋转,但位图质量也会有所下降:/


无论如何,谢谢你的帮助

我使用了这种配置,但仍然存在像素化问题:

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

已编辑:优化代码

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


你能用位图.createBitmap来做吗?您如何计算targetWidth和targetLight?简单的触发,我想,但有一个“更简单”的方法吗?请检查下面的答案,(对不起,我无法在注释中添加代码)应用此方法时质量变差。任何解决方案?更改canvas.drawBitmap(源代码、矩阵、新油漆());使用canvas.drawBitmap(源、矩阵、新绘制(Paint.ANTI_别名_标志));只是评论说这个过程非常需要内存,不应该在step方法中使用。你回答了错误的问题。他不想旋转视图,只想旋转其中的一个位图。根据我的经验,setFillAfter(bool)方法在Android API 11级及以下版本上无法正常工作。因此,开发人员无法对视图对象使用连续旋转事件,也无法在旋转后获得这些视图的旋转版本。所以@Mark Storer,如果你将动画持续时间设置为0或接近0,Macarse从逻辑的角度回答了这个问题。我认为上面的代码是经过多次尝试的变化后得到的。看起来mtx.setRotate(dir,x,y)应该自己完成这个任务,而不需要所有的pre/post内容。此外,您不需要重新设置新的
矩阵。它已经是身份了。前面的应答码也可以用。具有相同的质量问题。所有解决方案都存在相同的问题:位图质量降低更改画布。drawBitmap(源、矩阵、新绘制());使用canvas.drawBitmap(源、矩阵、新绘制(Paint.ANTI_别名_标志));您使用的配置是什么?我在下面发布了代码作为答案。无法将其写入评论中。非常感谢,先生:)你能试试设置过滤器位图吗,设置抖动选项是的,这很好用。非常感谢你,Sudar,你真的帮了我很多。添加链接到你自己的后续更新代码:尝试使用任意w或h旋转位图:Matrix Matrix=new Matrix();矩阵旋转后(90);bitmapPicture=Bitmap.createBitmap(bitmapPicture,0,0,bitmapPicture.getWidth(),bitmapPicture.getHeight(),matrix,true);这对我来说非常有效,因为我正在为图像点设置参数。在将位图绘制到画布时,您只需确保使用矩阵。您确定这是有效的吗?如果RotateBitmap()在循环中执行N次,根据位图的分辨率,可能会浪费大量内存以及所有新的矩阵对象分配。未测试,但docs表示:“如果源位图是不可变的,并且请求的子集与源位图本身相同,则返回源位图,并且不创建新位图。”对于矩阵对象,它只是转换坐标类。您可以自由优化代码以进行重复,并在循环中使用相同的矩阵对象。仅供参考,位图需要可变。”
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);