对Matrix中preTranslate()和postTranslate()的理解

时间:2022-03-07 04:03:31

前言

  因为在看郭霖大神的博客时有关于Matrix结合Camera实现图片的3D旋转,而其中Matrix的preTranslate()和postTranslate()方法当时不是太了解。关于android中对图片处理的内容我没怎么看过,所以不会也是在情理之中。但是既然想看会图片的3D旋转,这个又是必须要过的关,所以还是看了一点资料,发现原来只是我理解错了,并没有那么难,本文就是说说我当时是怎么理解的。

实现

  先来看一下效果图:

对Matrix中preTranslate()和postTranslate()的理解

  可以看到一张原图和三张处理之后的图,左边和右边的图的上部和底部不是对称的,只有中间的那张图是对称的,我希望得到的结果图片就是中间的那张。为什么会出现三张不同的旋转图片呢?原因是旋转中心不一样。

  我们先来看一下源码:

public class MainActivity extends AppCompatActivity {

private ImageView view2,view3,view4;

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view2 = (ImageView) findViewById(R.id.iv2);
view3 = (ImageView) findViewById(R.id.iv3);
view4 = (ImageView) findViewById(R.id.iv4);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.i004);
/**
* 旋转中心为(0,0)
*/

Matrix matrix = getMatrix();
Bitmap bit = getBitmap(bitmap, matrix);
view2.setImageBitmap(bit);

/**
* 旋转中心为(0,height/2)
*/

matrix = getMatrix();
matrix.preTranslate(0, -bitmap.getHeight() / 2);
matrix.postTranslate(0, bitmap.getHeight() / 2);
bit = getBitmap(bitmap, matrix);
view3.setImageBitmap(bit);

/**
* 旋转中心为(0,height)
*/

matrix = getMatrix();
matrix.preTranslate(0, -bitmap.getHeight());
matrix.postTranslate(0,bitmap.getHeight());
bit = getBitmap(bitmap, matrix);
view4.setImageBitmap(bit);

}

private Bitmap getBitmap(Bitmap bitmap, Matrix matrix) {
return Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
}

@NonNull
private Matrix getMatrix(){
Matrix matrix = new Matrix();
Camera camera = new Camera();
camera.save();
camera.rotateY(45);
camera.getMatrix(matrix);
camera.restore();
return matrix;
}
}

  左边图片:

  从源码中我们看到,左边图片我们对Matrix没有做任何处理,所以Camera的rotateY()方法在以y轴旋转的时候,旋转中心是(0,0),如下图所示:

对Matrix中preTranslate()和postTranslate()的理解

  因为旋转中心并不在图片的对称点上,所以得到的结果就是图片上下不对称。

  中间图片:
  中间的图片是对称的,那么是如何得到的呢?按照前面所说,因为旋转的中心是(0,0)不在图片的对称点上,那么我们只要让旋转中心在对称点上就可以了,这就要说preTranslate()和postTranslate()方法了,这两个方法可以实现我们所谓的旋转中心的改变,其实也没变,只是将图片以矩阵的形式进行操作,达到与旋转中心改变一样的效果罢了。

对Matrix中preTranslate()和postTranslate()的理解

matrix.preTranslate(0, -bitmap.getHeight());
matrix.postTranslate(0,bitmap.getHeight());

  这两行代码就是起到了这样的作用。preTranslate方法的作用是在旋转之间先把图片向上移动图片高度的一半的距离,这样图片就关于x轴对称了,然后再进行旋转的变换,postTranslate方法是在变换之后再将图片向下移动图片高度的一半的距离也即是回到了原来的位置,这样图片显示出来的结果就是对称的了。原理也很简单,旋转中心还是(0,0),只不过我们移动图片,这样进行旋转变换的时候就会得到对称的结果了。

小结

  好了,这个问题搞懂了,继续去看郭神的博客去了。