码迷,mamicode.com
首页 > 其他好文 > 详细

图片变换 矩阵 Bitmap Matrix

时间:2016-05-15 00:35:18      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:


Matrix矩阵介绍
在Android中,对图片的处理需要使用到Matrix类,Matrix是一个3 x 3的矩阵,内部就是个一维数组,内部有9个元素;可以通过setValues( float[])进行初始化,通过getValues(float[])拿到当前矩阵的值
具体坐标对应的属性为:
{MSCALE_X,MSKEW_X,MTRANS_X,
 MSKEW_YMSCALE_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方向上的缩放比例
       以上的set方法,均有对应的post和pre方法,Matrix调用一系列set、pre、post方法时,可视为将这些方法插入到一个队列。当然,按照队列中从头至尾的顺序调用执行。
其中pre表示在队头插入一个方法(相当于矩阵中的右乘),post表示在队尾插入一个方法(相当于矩阵中的左乘)set表示把当前队列清空,并且总是位于队列的最中间位置。当执行了一次set后,pre方法总是插入到set前部的队列的最前面,post方法总是插入到set后部的队列的最后面。
       错切变换,在数学上又称为Shear mapping(可译为“剪切变换”)或者Transvection(缩并),它是一种比较特殊的线性变换。错切变换的效果就是让所有点的x坐标(或者y坐标)保持不变,而对应的y坐标(或者x坐标)则按比例发生平移,且平移的大小和该点到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_widthet_heightet_scale_xet_scale_yet_rotateet_skew_xet_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(srcBmpmatrixpaint);
        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(srcBmpmatrixpaint);
        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(srcBmpmatrixpaint);
        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(srcBmpmatrixpaint);
        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(srcBmpmatrixpaint);
        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>





图片变换 矩阵 Bitmap Matrix

标签:

原文地址:http://www.cnblogs.com/baiqiantao/p/5494080.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!