Matrix矩阵介绍
在Android中,对图片的处理需要使用到Matrix类,Matrix是一个3 x 3的矩阵,内部就是个一维数组,内部有9个元素;可以通过setValues( float[])进行初始化,通过getValues(float[])拿到当前矩阵的值。 其具体坐标对应的属性为:{MSCALE_X,MSKEW_X,MTRANS_X, MSKEW_Y, MSCALE_Y,MTRANS_Y, MPERSP_0,MPERSP_1,MPERSP_2}比如我想知道现在x方向缩放比例: matrix.getValues(matrixValues); return matrixValues[Matrix.MSCALE_X];
操作示例 Matrix matrix = new Matrix(); matrix.setValues(new float[] { 1, 0, 0, 0, 1, 0, 0, 0, 1 }); x‘=1x+0y+0z(x坐标) y‘=0x+1y+0z(y坐标) z‘=0x+0y+1z(目前没用到) 如果第一行改为(0.5f,0,0),那么图像在x轴上将图像缩小到50%;如果第二行改为(0,2,0),那么图像在y轴上将图像放大到2倍; 如果第一行改为(1,0,100),那么图像在x轴上向右移动100像素;如果第二行改为(0,1,-100),那么图像在y轴上向上移动100像素;
为方便使用,Matrix提供了一些方法来控制图片变换:
- setTranslate(float dx,float dy):控制Matrix进行平移。X轴,右移为正;Y轴,下移为正
- setSkew(float kx,float ky):控制Matrix进行倾斜,kx、ky为X、Y方向上的比例
- setSkew(float kx,float ky,float px,float py):控制Matrix以px、py为轴心进行倾斜(错切),kx、ky为X、Y方向上的倾斜比例
- setRotate(float degrees):控制Matrix以(0,0)为轴心进行depress角度的旋转,顺时针为正
- setRotate(float degrees,float px,float py):设置Matrix以(px,py)为轴心旋转
- setScale(float sx,float sy):设置Matrix进行缩放,sx、sy为X、Y方向上的缩放比例。如果为负,那么会将该图像绘制到坐标系统的负值空间
- setScale(float sx,float sy,float px,float py):设置Matrix以(px,py)为轴心进行缩放,sx、sy为X、Y方向上的缩放比例
PS:在Canvas上绘制图形时既可使用Matrix,也可使用ColorMatrix来改变在Canvas对象上绘制的Paint对象。
演示代码
public class MainActivity extends Activity { private ImageView iv_new; private Bitmap srcBmp;//原图 private Bitmap alterBitmap;//创建的可修改的图 private Canvas canvas;//画板 private Paint paint;//画笔 private Matrix matrix;//矩阵 private float[] matrixValues = new float[3 * 3];//矩阵中的数组,默认[1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] //可以设置的参数 private EditText et_width, et_height, et_scale_x, et_scale_y, et_rotate, et_skew_x, et_skew_y; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_matrix); iv_new = (ImageView) findViewById(R.id.iv_new); et_width = (EditText) findViewById(R.id.et_width); et_height = (EditText) findViewById(R.id.et_height); et_scale_x = (EditText) findViewById(R.id.et_scale_x); et_scale_y = (EditText) findViewById(R.id.et_scale_y); et_rotate = (EditText) findViewById(R.id.et_rotate); et_skew_x = (EditText) findViewById(R.id.et_skew_x); et_skew_y = (EditText) findViewById(R.id.et_skew_y); srcBmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon); paint = new Paint(); matrix = new Matrix(); }
private void init() { int newWidth = (int) (srcBmp.getWidth() * Float.parseFloat(et_width.getText().toString())); int newHeight = (int) (srcBmp.getHeight() * Float.parseFloat(et_height.getText().toString())); //创建原图的一个副本。 此副本是可修改的。创建的是一个空白的图形。 alterBitmap = Bitmap.createBitmap(newWidth, newHeight, srcBmp.getConfig());//Config.ARGB_8888,32位;Config.RGB_565,24位,忽略透明度 canvas = new Canvas(alterBitmap);//画板的大小就是我们创建的副本的大小 matrix.reset();//重置矩阵 } //复制 public void copy(View view) { init(); matrix.getValues(matrixValues); //MSCALE_X, MSKEW_X, MTRANS_X, MSKEW_Y, MSCALE_Y, MTRANS_Y, MPERSP_0, MPERSP_1, MPERSP_2 Log.i("bqt", Arrays.toString(matrixValues));//[1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] canvas.drawBitmap(srcBmp, matrix, paint); iv_new.setImageBitmap(alterBitmap); } //缩放 public void zoom(View view) { init(); matrix.setScale(Float.parseFloat(et_scale_x.getText().toString()), 1.0f * Float.parseFloat(et_scale_y.getText().toString())); matrix.getValues(matrixValues); Log.i("bqt", Arrays.toString(matrixValues));//[0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] Log.i("bqt", matrixValues[Matrix.MSCALE_X] + "--" + matrixValues[Matrix.MSCALE_Y]);//0.5--1.0 canvas.drawBitmap(srcBmp, matrix, paint); iv_new.setImageBitmap(alterBitmap); } //旋转。这里有一个bug:当进入界面后第一次点击的是"旋转"时,图片并没有旋转;若第一次点击的是其他按钮,则之后再点击就正常了,不知道为什么! public void rotate(View view) { init(); //注意,getLeft()、getTop()等获取到的是控件【左上角】相对于【父控件】相应部位的值,setRotate中的参数为相对图片【自身】【左上角】的距离 matrix.setRotate(Float.parseFloat(et_rotate.getText().toString()), iv_new.getWidth() / 2, iv_new.getHeight() / 2); matrix.getValues(matrixValues); Log.i("bqt", Arrays.toString(matrixValues));//[0.0, -1.0, 144.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0] Log.i("bqt", matrixValues[Matrix.MSKEW_X] + "--" + matrixValues[Matrix.MSKEW_Y]);//-1.0--1.0 Log.i("bqt", matrixValues[Matrix.MTRANS_X] + "--" + matrixValues[Matrix.MTRANS_Y]);//144.0--0.0 canvas.drawBitmap(srcBmp, matrix, paint); iv_new.setImageBitmap(alterBitmap); } //错切 public void skew(View view) { init(); matrix.setSkew(Float.parseFloat(et_skew_x.getText().toString()), Float.parseFloat(et_skew_y.getText().toString()));//kx、ky为X、Y方向上的比例 matrix.getValues(matrixValues); Log.i("bqt", Arrays.toString(matrixValues));//[1.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] Log.i("bqt", matrixValues[Matrix.MSKEW_X] + "--" + matrixValues[Matrix.MSKEW_Y]);//0.5--0.0 canvas.drawBitmap(srcBmp, matrix, paint); iv_new.setImageBitmap(alterBitmap); } //镜面(移动+缩放) public void mirror(View view) { init(); matrix.setScale(-1.0f, 1.0f);//y不变,x变成负的(此时已经是镜面效果了,但是图片不是在画布范围,所以无法显示) matrix.postTranslate(srcBmp.getWidth(), 0);//向右移动一个图片高度的距离 matrix.getValues(matrixValues); Log.i("bqt", Arrays.toString(matrixValues));//[-1.0, 0.0, 144.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] Log.i("bqt", matrixValues[Matrix.MSCALE_X] + "--" + matrixValues[Matrix.MSCALE_Y]);//-1.0--1.0 Log.i("bqt", matrixValues[Matrix.MTRANS_X] + "--" + matrixValues[Matrix.MTRANS_Y]);//144.0--0.0 canvas.drawBitmap(srcBmp, matrix, paint); iv_new.setImageBitmap(alterBitmap); } }
演示布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:gravity="center_horizontal" android:orientation="horizontal" > <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="copy" android:text="复制" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="zoom" android:text="缩放" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="rotate" android:text="旋转" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="skew" android:text="错切" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="mirror" android:text="镜面" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="画布横向缩放倍数" android:textSize="13sp" /> <EditText android:id="@+id/et_width" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:minEms="3" android:text="1" android:textSize="13sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="画布纵向缩放倍数" android:textSize="13sp" /> <EditText android:id="@+id/et_height" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:minEms="3" android:text="1" android:textSize="13sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="图片横向缩放倍数" android:textSize="13sp" /> <EditText android:id="@+id/et_scale_x" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:minEms="3" android:text="0.5" android:textSize="13sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="图片纵向缩放倍数" android:textSize="13sp" /> <EditText android:id="@+id/et_scale_y" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:minEms="3" android:text="1" android:textSize="13sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="中心旋转角度" android:textSize="13sp" /> <EditText android:id="@+id/et_rotate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:minEms="3" android:text="90" android:textSize="13sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="错切相对值" android:textSize="13sp" /> <EditText android:id="@+id/et_skew_x" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:minEms="3" android:text="0.5" android:textSize="13sp" /> <EditText android:id="@+id/et_skew_y" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:minEms="3" android:text="0" android:textSize="13sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="horizontal" > <ImageView android:id="@+id/iv_old" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#0000ff" android:src="@drawable/icon" /> <ImageView android:id="@+id/iv_new" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="1dp" android:background="#00ffff" /> </LinearLayout> </LinearLayout>
时间: 2024-10-11 03:37:15