Android Matrix(变形矩阵)
来源:互联网 发布:云南为什么乱 知乎 编辑:程序博客网 时间:2024/05/16 18:11
概要:
Matrix(矩阵),这是一个数学的概念。通常的nxm(n行,m列)行列数是不受限制的。但这里主要讲的是
3x3矩阵(3行3列)如图:
Matrix对图形的变形通常有如下四种形式:
Translate 平移变换
Rotate 旋转变换
Scale 缩放变换
Skew 错切变换
从字面上的意思,MACALE负责缩放,MSKEW负责错切,MARANS负责平移。MPERSP 用于处理透视的
变化(不常用),当然我们不能完全按照上面的意思理解。
针对上面的四种变换,Android进行了封装,提供三种方法setXX(设值),preXX(前乘),postXX(后乘)。
分析:
一,Translate 平移变换
将一个点 ,平移到点的位置,如下图 :
由图可知:
用矩阵来表示的话:
二,Rotate 旋转变换
2.1将一个点 ,围绕坐标原点(0,0)顺时针旋转,如图:
其中点到原点的距离为r。到原点连线与X轴正方向的夹角为α。
有图可知:
用矩阵表示为:
2.2 将一个点 ,围绕坐标某个点,顺时针旋转,
有上面的推理可知:
矩阵变换:
分析矩阵表达式:
1.
是将坐标原点移动到点后, 的新坐标。
2.
是将上一步变换后的,围绕新的坐标原点顺时针旋转 。
3.
经过上一步旋转变换后,再将坐标原点移回到原来的坐标原点。
所以,围绕某一点进行旋转变换,可以分成3个步骤,即首先将坐标原点移至该点,然后围绕新
的坐标原点进行旋转变换,再然后将坐标原点移回到原先的坐标原点。
三,Scale 缩放变换
理论上而言,一个点是不存在什么缩放变换的,这里需要说明一下,因为所有图像都是由点组成,所以图像的
变化是由所有的点的变化来完成的(这也是前面分析的都是点的变化的原因)。例如在这里如果图像在x轴和
y轴方向分别放大k1和k2倍的话,那么图像中的所有点的x坐标和y坐标均会分别放大k1和k2倍,即
用矩阵表示就是:
缩放变换比较好理解,就不多说了。
四,错切变化:
错切变换就是让所有点的x坐标(或者y坐标)保持不变,而对应的y坐标(或者x坐标)则按比例发生平移,
如图所示:
1,各点的y坐标保持不变,但其x坐标则按比例发生了平移。这种情况将水平错切。
2,各点的x坐标保持不变,但其y坐标则按比例发生了平移。这种情况叫垂直错切。
假定一个点经过错切变换后得到,对于水平错切而言,应该有如下关系:
用矩阵表示为:
同理,对于垂直错切,可以有:
在数学上严格的错切变换就是上面这样的。在Android中除了有上面说到的情况外,还可以同时进行水平、
垂直错切,那么形式上就是:
应用:
我们设置九个EditText,自己设置矩阵。然后根据矩阵取变换图像。
public class MatrixActivity extends Activity { private EditText[] edits; private Button btn_change, btn_reset; private ImageView imageView; private static final String tag = "tag_matrix"; Matrix matrix = new Matrix(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_matrix); initViews(); btn_change.setOnClickListener(onClickListener); btn_reset.setOnClickListener(onClickListener); } private void initViews() { imageView = (ImageView) findViewById(R.id.iv_show); edits = new EditText[9]; for (int i = 0; i < 9; i++) { edits[i] = (EditText) findViewById(R.id.et_0 + i); } btn_change = (Button) findViewById(R.id.btn_change); btn_reset = (Button) findViewById(R.id.btn_reset); } View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_change: changeImage(); break; case R.id.btn_reset: resetImage(); break; } } }; private void changeImage() { LogUtil.i(tag, "changeImage"); float[] data = new float[9]; for (int i = 0; i < edits.length; i++) { String txt = edits[i].getText().toString(); try { if ("".equals(txt)) { data[i] = 0; } else { data[i] = Float.parseFloat(txt); } } catch (Exception e) { data[i] = 0; } LogUtil.i(tag, "" + data[i]); } matrix.setValues(data); BitmapDrawable bitmapDrawable = (BitmapDrawable) getResources().getDrawable(R.drawable.aa2); Bitmap tempBitmap = bitmapDrawable.getBitmap(); Bitmap bitmap = Bitmap.createBitmap(tempBitmap, 0, 0, tempBitmap.getWidth(), tempBitmap.getHeight(), matrix, true); imageView.setImageBitmap(bitmap); } private void resetImage() { LogUtil.i(tag, "resetImage"); matrix.reset(); imageView.setImageResource(R.drawable.aa2); }}布局文件:res/layout/activity_matrix
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/ll_title" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="原图"/> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:text="变换图"/> </LinearLayout> <ImageView android:id="@+id/iv_init" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:src="@drawable/aa2" android:layout_margin="10dp" android:layout_below="@+id/ll_title"/> <RelativeLayout android:layout_below="@+id/ll_title" android:layout_toRightOf="@+id/iv_init" android:layout_above="@+id/rl_input" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/iv_show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:scaleType="center" android:src="@drawable/aa2"/> </RelativeLayout> <RelativeLayout android:id="@+id/rl_input" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_above="@+id/ll_button"> <EditText android:id="@+id/et_0" android:layout_width="50dp" android:layout_marginLeft="20dp" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_1" android:layout_width="50dp" android:layout_centerHorizontal="true" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_2" android:layout_width="50dp" android:layout_height="wrap_content" android:layout_marginRight="20dp" android:layout_alignParentRight="true"/> <EditText android:id="@+id/et_3" android:layout_width="50dp" android:layout_margin="20dp" android:layout_below="@+id/et_0" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_4" android:layout_width="50dp" android:layout_margin="20dp" android:layout_below="@+id/et_0" android:layout_centerHorizontal="true" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_5" android:layout_width="50dp" android:layout_margin="20dp" android:layout_below="@+id/et_0" android:layout_alignParentRight="true" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_6" android:layout_width="50dp" android:layout_marginLeft="20dp" android:layout_marginBottom="20dp" android:layout_below="@+id/et_3" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_7" android:layout_width="50dp" android:layout_below="@+id/et_3" android:layout_centerHorizontal="true" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_8" android:layout_width="50dp" android:layout_marginRight="20dp" android:layout_marginBottom="20dp" android:layout_below="@+id/et_3" android:layout_alignParentRight="true" android:layout_height="wrap_content" /> </RelativeLayout> <LinearLayout android:id="@+id/ll_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:orientation="horizontal"> <Button android:id="@+id/btn_change" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="change"/> <Button android:id="@+id/btn_reset" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="reset"/> </LinearLayout> </RelativeLayout>
3.1缩放变换(宽高同时放大到2倍):
3.3 绕原点旋转变换(旋转30度)。
4,平移变换,使用这种方式(
Bitmap.createBitmap(tempBitmap, 0, 0, tempBitmap.getWidth(), tempBitmap.getHeight(), matrix, true))不起作用(平移并不会改变图像本身)。
可改用Canvas。drawBitmap(Bitmap, Matrix, Paint);
我们修改一下代码:
BitmapDrawable bitmapDrawable = (BitmapDrawable) getResources().getDrawable(R.drawable.aa2); Bitmap tempBitmap = bitmapDrawable.getBitmap(); Bitmap bitmap = Bitmap.createBitmap(tempBitmap.getWidth(), tempBitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); MatrixDrawable matrixDrawable = new MatrixDrawable(tempBitmap, matrix); matrixDrawable.draw(canvas);
其中MatrixDrawable的代码:
public class MatrixDrawable extends Drawable { private final static String tag = "MatrixDrawable"; //画笔 Paint mPaint; //绘图矩阵 Matrix mMatrix; //原始图 Bitmap mBitmap; //矩阵元素存储的数组 float[] params; Bitmap temp; MatrixDrawable(Bitmap bitmap, Matrix matrix) { this.mBitmap = bitmap; this.mMatrix = matrix; mPaint = new Paint(); mPaint.setAntiAlias(true); } @Override public void draw(Canvas canvas) { canvas.drawBitmap(mBitmap, mMatrix, mPaint); } @Override public int getIntrinsicWidth() { if (mBitmap != null) { return mBitmap.getWidth(); } return super.getIntrinsicWidth(); } @Override public int getIntrinsicHeight() { if (mBitmap != null) { return mBitmap.getHeight(); } return super.getIntrinsicHeight(); } @Override public void setAlpha(int alpha) { mPaint.setAlpha(alpha); } @Override public void setColorFilter(ColorFilter colorFilter) { mPaint.setColorFilter(colorFilter); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } public Matrix getmMatrix(){ return mMatrix; }}效果如图:
- Android Matrix(变形矩阵)
- Android变形矩阵——Matrix
- 变形--矩阵 matrix()
- Android的Matrix(矩阵)
- Transform Matrix(矩阵变形)-Css3演示
- Android矩阵原理详解(Matrix,ColorMatrix)
- Android矩阵原理详解(Matrix,ColorMatrix)
- Android矩阵原理详解(Matrix,ColorMatrix)
- Android矩阵原理详解(Matrix,ColorMatrix)
- Android矩阵原理详解(Matrix,ColorMatrix)
- Android Matrix矩阵详解
- Android-Matrix矩阵
- Matrix(矩阵操作)
- 矩阵(Matrix)
- Android中关于矩阵(Matrix)前乘后乘的一些认识
- Android中关于矩阵(Matrix)前乘后乘的一些认识
- Android中关于矩阵(Matrix)前乘后乘的一些认识
- Android中关于矩阵(Matrix)前乘后乘的一些认识
- Android 单元测试之JUnit
- 面试感悟---一名3年工作经验的程序员应该具备的技能
- java读取文件并获得文件编码,转换为指定编码的工具类代码
- 首次百万量级数据处理
- 欢迎使用CSDN-markdown编辑器
- Android Matrix(变形矩阵)
- Could not find gem 'jquery-rails (~> 3.1.1)
- mac 常用命令
- CVPR 2017-02-16
- Intellij 使用总结
- 微信网页版接口
- Nginx+tomcat+memcached
- linux Shell脚本学习汇集的问题
- Intellij Idea 工具在java文件中怎么避免 import .*包,以及import包顺序的问题