图片变换 矩阵 Bitmap Matrix

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方向上的缩放比例
       以上的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_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>

来自为知笔记(Wiz)

时间: 2024-10-11 03:37:15

图片变换 矩阵 Bitmap Matrix的相关文章

图片变换【Matrix】矩阵 简介

Matrix矩阵介绍 官方文档地址:https://developer.android.com/reference/android/graphics/Matrix.html 在Android中,对图片的处理需要使用到Matrix类,Matrix是一个3 x 3的矩阵,内部就是个一维数组,内部有9个元素,可以通过setValues(float[])进行初始化,通过getValues(float[])把拿到的矩阵值赋给传入的数组. 源码中的介绍就一句话:The Matrix class holds

android图片缩小和放大Matrix

/**Bitmap放大的方法*/ private static Bitmap big(Bitmap bitmap) { Matrix matrix = new Matrix(); matrix.postScale(1.5f,1.5f); //长和宽放大缩小的比例 Bitmap resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true); return resizeBmp;

OpenGL投影矩阵(Projection Matrix)构造方法

(翻译,图片也来自原文) 一.概述 绝大部分计算机的显示器是二维的(a 2D surface).在OpenGL中一个3D场景需要被投影到屏幕上成为一个2D图像(image).这称为投影变换(参见这或这),需要用到投影矩阵(projection matrix). 首先,投影矩阵会把所有顶点坐标从eye coordinates(观察空间,eye space或view space)变换到裁剪坐标(clip coordinated,属于裁剪空间,clip space).然后,这些裁剪坐标被变换到标准化设

【Math for ML】矩阵分解(Matrix Decompositions) (上)

I. 行列式(Determinants)和迹(Trace) 1. 行列式(Determinants) 为避免和绝对值符号混淆,本文一般使用\(det(A)\)来表示矩阵\(A\)的行列式.另外这里的\(A∈R^{n×n}\)默认是方阵,因为只有方阵才能计算行列式. 行列式如何计算的就不在这里赘述了,下面简要给出行列式的各种性质和定理. 定理1:当且仅当一个方阵的行列式不为0,则该方阵可逆. 定理2:方阵\(A\)的行列式可沿着某一行或某一列的元素展开,形式如下: 沿着第\(i\)行展开:\[de

图片文件和Bitmap之间的转换

图片文件转为Bitmap对象String filePath="c:/01.jpg"; Bitmap bitmap=BitmapFactory.decodeFile(filePath); 如果图片过大,可能导致Bitmap对象装不下图片解决办法:String filePath="c:/01.jpg"; Bitmap bitmap=BitmapFactory.decodeFile(filePath,getBitmapOption(2)); //将图片的长和宽缩小味原来的

android 将图片通过base64转换为String 将图片String转换为Bitmap

1.Bitmap转换为图片字符串 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); //该方法用来压缩图片,第一个参数为图片格式,第二个参数为截取图片的保留率,如当前为90,则保留之前图片90%的区域 bitmap.compress(Bitmap

android将drawable下的图片转换成bitmap

将drawable下的图片转换成bitmap 1. Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.xxx); 2.Resources r = this.getContext().getResources();      Inputstream is = r.openRawResource(R.drawable.xxx);      BitmapDrawable  bmpDraw = new Bitm

矩阵(matrix)

我们定义一个矩阵的权值为这个矩阵四个角上的数值的最小值.现在小M有一个矩阵,他想在这个矩阵中寻找到一个权值最大的子矩阵,请你告诉他这个最大权值.(距形规模最大为2000*2000) 比赛 看到第二题那么大的数据 就他妈不想写了..直接写了个爆搜看第三题,也就是这题..总感觉可以做的感觉,但就是想不出好的办法,爆搜估计也就10分,感觉不大合算,自己写了几组数据,感觉答案一般都会在2*2的矩形里,就直接枚举了2*2的矩形,还怀揣着骗个30~40的分,结果逗比了,0分..标准算法应该是二分答案,将不比

DIV css中cursor属性详解-鼠标移到图片变换鼠标形状 (转)

css中cursor属性详解-鼠标移到图片变换鼠标形状 语法: cursor : auto | all-scroll | col-resize| crosshair | default | hand | move | help | no-drop | not-allowed | pointer | progress | row-resize | text | vertical-text | wait | *-resize | url ( url )  取值: auto  :   默认值.浏览器根