一、概述

 1. 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类。Android中的Matrix是一个3 x 3的矩阵,其内容如下

  

2.Matrix的对图像的处理可分为四类基本变换:

  Translate           平移变换

  Rotate                旋转变换

  Scale                  缩放变换

  Skew                  错切变换

针对每种变换,Android提供了pre、set和post三种操作方式。其中
set用于设置Matrix中的值。
pre是先乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。先乘相当于矩阵运算中的右乘。
post是后乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。后乘相当于矩阵运算中的左乘。

除平移变换(Translate)外,旋转变换(Rotate)、缩放变换(Scale)和错切变换(Skew)都可以围绕一个中心点来进行,如果不指定,在默认情况下是围绕(0, 0)来进行相应的变换的。

  

二、常用操作

1.平移  

  1. matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());

2.缩放

  1. matrix.setScale(2f, 2f);

3.旋转

  1. //第一种方式
  2. //旋转 围绕图片中心
  3. matrix.setRotate(45f,view.getImageBitmap().getWidth()/2f,view.getImageBitmap().getHeight()/2f);
  4. //平移
  5. matrix.postTranslate(view.getImageBitmap().getWidth()*1.5f,0f);
  6.  
  7. //第二种方式
  8. //旋转 中心点(0,0)
  9. matrix.setRotate(45f);
  10.  
  11. //先将图片中心移到(0,0),旋转后再移到原位置
  12. matrix.preTranslate(-view.getImageBitmap().getWidth()/2f,-view.getImageBitmap().getHeight()/2f);
  13. matrix.postTranslate(view.getImageBitmap().getWidth()*2f,view.getImageBitmap().getHeight()/2f);

4.错切

  1.      matrix.setSkew(0.5f,0f);//水平
  2. matrix.setSkew(0f,0.5f);//竖直
  3. matrix.setSkew(0.5f,0.5f);//水平和数值

5.对称

 1)x轴对称

  1. float matrix_values[] = {1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};
    matrix.setValues(matrix_values);

 2)Y轴对称

  1. float matrix_values[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};
    matrix.setValues(matrix_values);

 3)y=x对称

  1. float matrix_values[] = {0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f};
    matrix.setValues(matrix_values);

三、代码

1.xml文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. >
  7. <RelativeLayout
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"
  10. android:id="@+id/rl"
  11. >
  12. <com.example.dhj.bitmapdemo.TransformMatrixView
  13. android:layout_width="match_parent"
  14. android:layout_height="match_parent"
  15. android:id="@+id/view"
  16. />
  17. </RelativeLayout>
  18.  
  19. <RelativeLayout
  20. android:layout_width="match_parent"
  21. android:layout_height="match_parent"
  22. android:visibility="visible"
  23.  
  24. >
  25.  
  26. <Button
  27. android:id="@+id/button"
  28. android:layout_width="wrap_content"
  29. android:layout_height="wrap_content"
  30. android:layout_alignParentBottom="true"
  31. android:layout_alignParentLeft="true"
  32. android:layout_alignParentStart="true"
  33. android:layout_marginBottom="135dp"
  34. android:onClick="click"
  35. android:text="平移" />
  36.  
  37. <Button
  38. android:id="@+id/button2"
  39. android:layout_width="wrap_content"
  40. android:layout_height="wrap_content"
  41. android:layout_alignBaseline="@+id/button"
  42. android:layout_alignBottom="@+id/button"
  43. android:layout_marginLeft="17dp"
  44. android:layout_marginStart="17dp"
  45. android:layout_toEndOf="@+id/button"
  46. android:layout_toRightOf="@+id/button"
  47. android:onClick="click"
  48. android:text="旋转" />
  49.  
  50. <Button
  51. android:id="@+id/button3"
  52. android:layout_width="wrap_content"
  53. android:layout_height="wrap_content"
  54. android:layout_alignBottom="@+id/button2"
  55. android:layout_marginLeft="35dp"
  56. android:layout_marginStart="35dp"
  57. android:layout_toEndOf="@+id/button2"
  58. android:layout_toRightOf="@+id/button2"
  59. android:onClick="click"
  60. android:text="水平倾斜" />
  61.  
  62. <Button
  63. android:id="@+id/button4"
  64. android:layout_width="wrap_content"
  65. android:layout_height="wrap_content"
  66. android:layout_alignBaseline="@+id/button5"
  67. android:layout_alignBottom="@+id/button5"
  68. android:layout_alignParentLeft="true"
  69. android:layout_alignParentStart="true"
  70. android:onClick="click"
  71. android:text="竖直倾斜" />
  72.  
  73. <Button
  74. android:id="@+id/button5"
  75. android:layout_width="wrap_content"
  76. android:layout_height="wrap_content"
  77. android:layout_alignLeft="@+id/button2"
  78. android:layout_alignStart="@+id/button2"
  79. android:layout_below="@+id/button2"
  80. android:onClick="click"
  81. android:text="水平竖直倾斜" />
  82.  
  83. <Button
  84. android:id="@+id/button6"
  85. android:layout_width="wrap_content"
  86. android:layout_height="wrap_content"
  87. android:layout_alignLeft="@+id/button3"
  88. android:layout_alignStart="@+id/button3"
  89. android:layout_below="@+id/button3"
  90. android:onClick="click"
  91. android:text="x轴对称" />
  92.  
  93. <Button
  94. android:id="@+id/button7"
  95. android:layout_width="wrap_content"
  96. android:layout_height="wrap_content"
  97. android:layout_alignParentLeft="true"
  98. android:layout_alignParentStart="true"
  99. android:layout_below="@+id/button4"
  100. android:layout_marginTop="15dp"
  101. android:onClick="click"
  102. android:text="y轴对称" />
  103.  
  104. <Button
  105. android:id="@+id/button8"
  106. android:layout_width="wrap_content"
  107. android:layout_height="wrap_content"
  108. android:layout_alignBottom="@+id/button7"
  109. android:layout_alignLeft="@+id/button5"
  110. android:layout_alignStart="@+id/button5"
  111. android:onClick="click"
  112. android:text="y=x对称" />
  113.  
  114. <Button
  115. android:id="@+id/button11"
  116. android:layout_width="wrap_content"
  117. android:layout_height="wrap_content"
  118. android:layout_alignLeft="@+id/button6"
  119. android:layout_alignStart="@+id/button6"
  120. android:layout_alignTop="@+id/button8"
  121. android:onClick="click"
  122. android:text="缩放" />
  123.  
  124. </RelativeLayout>
  125.  
  126. </FrameLayout>

  

2.自定义view

  1. class TransformMatrixView extends ImageView
  2. {
  3. private Bitmap bitmap;
  4. private Matrix matrix;
  5. public TransformMatrixView(Context context)
  6. {
  7. super(context);
  8. Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.p1);
  9. bitmap=resizeBitmap(b,162,251);
  10. matrix = new Matrix();
  11. setBackgroundColor(Color.parseColor("#3f51b5"));
  12. }
  13.  
  14. public TransformMatrixView(Context context, @Nullable AttributeSet attrs) {
  15. super(context, attrs);
  16. Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.p1);
  17. bitmap=resizeBitmap(b,162,251);
  18. matrix = new Matrix();
  19. // setBackgroundColor(Color.parseColor("#3f51b5"));
  20. }
  21.  
  22. @Override
  23. protected void onDraw(Canvas canvas)
  24. {
  25. // 画出原图像
  26. canvas.drawBitmap(bitmap, 0, 0, null);
  27. // 画出变换后的图像
  28. canvas.drawBitmap(bitmap, matrix, null);
  29. super.onDraw(canvas);
  30. }
  31.  
  32. @Override
  33. public void setImageMatrix(Matrix matrix)
  34. {
  35. this.matrix.set(matrix);
  36. super.setImageMatrix(matrix);
  37. }
  38.  
  39. public Bitmap getImageBitmap()
  40. {
  41. return bitmap;
  42. }
  43.  
  44. /**
  45. * 使用Matrix将Bitmap压缩到指定大小
  46. * @param bitmap
  47. * @param w
  48. * @param h
  49. * @return
  50. */
  51. public static Bitmap resizeBitmap(Bitmap bitmap, int w, int h)
  52. {
  53. int width = bitmap.getWidth();
  54. int height = bitmap.getHeight();
  55.  
  56. float scaleWidth = ((float) w) / width;
  57. float scaleHeight = ((float) h) / height;
  58.  
  59. Matrix matrix = new Matrix();
  60. matrix.postScale(scaleWidth, scaleHeight);
  61.  
  62. Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width,
  63. height, matrix, true);
  64. return resizedBitmap;
  65. }
  66. }

3.activity

  1. public class MainActivity extends Activity {
  2. private TransformMatrixView view;
  3. Matrix matrix= new Matrix();
  4. @Override
  5. public void onCreate(Bundle savedInstanceState)
  6. {
  7. super.onCreate(savedInstanceState);
  8. requestWindowFeature(Window.FEATURE_NO_TITLE);
  9. setContentView(R.layout.activity_main);
  10. view= (TransformMatrixView) findViewById(R.id.view);
  11.  
  12. }
  13.  
  14. public void click(View v){
  15. switch (v.getId()){
  16. case R.id.button:
  17. tranlate();
  18. break;
  19. case R.id.button2:
  20. rorate();
  21. break;
  22. case R.id.button3:
  23. skewhorizontal();
  24. break;
  25. case R.id.button4:
  26. skewVertical();
  27. break;
  28. case R.id.button5:
  29. skew();
  30. break;
  31. case R.id.button6:
  32. symmetryHorizontal();
  33. break;
  34. case R.id.button7:
  35. symmetryVertical();
  36. break;
  37. case R.id.button8:
  38. symmetry();
  39. break;
  40. case R.id.button11:
  41. scale();
  42. break;
  43.  
  44. }
  45. view.setImageMatrix(matrix);
  46. // view.invalidate();
  47. }
  48.  
  49. //平移
  50. private void tranlate(){
  51. // 输出图像的宽度和高度(162 x 251)
  52. // Log.e("TestTransformMatrixActivity", "image size: width x height = " + view.getImageBitmap().getWidth() + " x " + view.getImageBitmap().getHeight());
  53. // 1. 平移
  54. matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());
  55. // 在x方向平移view.getImageBitmap().getWidth(),在y轴方向view.getImageBitmap().getHeight()
  56.  
  57. }
  58.  
  59. //旋转
  60. private void rorate(){
  61. //第一种方式
  62. //旋转 围绕图片中心
  63. matrix.setRotate(45f,view.getImageBitmap().getWidth()/2f,view.getImageBitmap().getHeight()/2f);
  64. //平移
  65. matrix.postTranslate(view.getImageBitmap().getWidth()*1.5f,0f);
  66.  
  67. //第二种方式
  68. //旋转 中心点(0,0)
  69. matrix.setRotate(45f);
  70.  
  71. //先将图片中心移到(0,0),旋转后再移到原位置
  72. matrix.preTranslate(-view.getImageBitmap().getWidth()/2f,-view.getImageBitmap().getHeight()/2f);
  73. matrix.postTranslate(view.getImageBitmap().getWidth()*2f,view.getImageBitmap().getHeight()/2f);
  74.  
  75. }
  76.  
  77. //缩放
  78. private void scale(){
  79. matrix.setScale(2f, 2f);
  80. matrix.postTranslate(view.getImageBitmap().getWidth(),view.getImageBitmap().getHeight());
  81.  
  82. }
  83.  
  84. //水平 倾斜
  85. private void skewhorizontal(){
  86. // matrix.setSkew(0.5f, 0f);
  87. // matrix.postTranslate(view.getImageBitmap().getWidth(), 0f);
  88. matrix.setSkew(0.5f,0f);
  89. matrix.postTranslate(view.getImageBitmap().getWidth(),0f);
  90.  
  91. }
  92.  
  93. //竖直 倾斜
  94. private void skewVertical(){
  95. matrix.setSkew(0f,0.5f);
  96. matrix.postTranslate(view.getImageBitmap().getWidth(),0f);
  97.  
  98. }
  99.  
  100. //倾斜 水平和竖直
  101. private void skew(){
  102. matrix.setSkew(0.5f,0.5f);
  103. matrix.postTranslate(view.getImageBitmap().getWidth(),0f);
  104. }
  105.  
  106. //x轴对称
  107. private void symmetryHorizontal(){
  108. float matrix_values[] = {1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};
  109. matrix.setValues(matrix_values);
  110. matrix.postTranslate(0f,view.getImageBitmap().getHeight()*2);
  111. }
  112.  
  113. //y轴对称
  114. private void symmetryVertical(){
  115. float matrix_values[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};
  116. matrix.setValues(matrix_values);
  117. matrix.postTranslate(view.getImageBitmap().getWidth()*2,0f);
  118. }
  119.  
  120. //对称 y=x
  121. private void symmetry(){
  122. float matrix_values[] = {0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f};
  123. matrix.setValues(matrix_values);
  124. matrix.postTranslate(view.getImageBitmap().getWidth()+view.getImageBitmap().getHeight(),
  125. view.getImageBitmap().getHeight()+view.getImageBitmap().getWidth());
  126. }
  127.  
  128. }

四、效果

  

参考:

Android中图像变换Matrix的原理、代码验证和应用

Android绘图之Matrix的更多相关文章

  1. 论文第5章:Android绘图平台的实现

    面向移动设备的矢量绘图平台设计与实现 Design and Implementation of Mobile Device-oriented Vector Drawing Platform 引用本论文 ...

  2. Android群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧

    第六章 Android绘图机制与处理技巧 1.屏幕尺寸信息屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DP ...

  3. 第三章 Android绘图机制与处理技巧

    1.屏幕尺寸信息 屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DPI(Dots Per Inch),它是对 ...

  4. Android群英传笔记——第六章:Android绘图机制与处理技巧

    Android群英传笔记--第六章:Android绘图机制与处理技巧 一直在情调,时间都是可以自己调节的,不然世界上哪有这么多牛X的人 今天就开始读第六章了,算日子也刚好一个月了,一个月就读一半,这效 ...

  5. Android为TV端助力 转载:Android绘图Canvas十八般武器之Shader详解及实战篇(下)

    LinearGradient 线性渐变渲染器 LinearGradient中文翻译过来就是线性渐变的意思.线性渐变通俗来讲就是给起点设置一个颜色值如#faf84d,终点设置一个颜色值如#CC423C, ...

  6. Android中图像变换Matrix的原理、代码验证和应用(一)

    第一部分 Matrix的数学原理 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类.Android中的Matrix是一个3 x 3的矩阵,其内容如下: Matri ...

  7. android 绘图之Canvas,Paint类

    Canvas,Paint 1.在android 绘图但中经常要用到Canvas和Paint类,Canvas好比是一张画布,上面已经有你想绘制图画的轮廓了,而Paint就好比是画笔,就要给Canvas进 ...

  8. Android绘图机制(四)——使用HelloCharts开源框架搭建一系列炫酷图表,柱形图,折线图,饼状图和动画特效,抽丝剥茧带你认识图表之美

    Android绘图机制(四)--使用HelloCharts开源框架搭建一系列炫酷图表,柱形图,折线图,饼状图和动画特效,抽丝剥茧带你认识图表之美 这里为什么不继续把自定义View写下去呢,因为最近项目 ...

  9. Android绘图机制(三)——自定义View的实现方式以及半弧圆新控件

    Android绘图机制(三)--自定义View的三种实现方式以及实战项目操作 在Android绘图机制(一)--自定义View的基础属性和方法 里说过,实现自定义View有三种方式,分别是 1.对现有 ...

随机推荐

  1. datasnap 上传/下载大文件(本Demo以图传片文件为例)

    好久没写技术文了 datasnap传大流. 完整代码,同时感谢叶兄传流的指点,(只公开十天) 附:下面代码,转载请注明出处 ::code 服务端: function TServerMethods1.D ...

  2. 搭建Ganglia乱码及其他问题总汇

    搭建Ganglia乱码及其他问题 搭建完Ganglia监控后图像显示正常,但是文字却显示都是小方框,最后确定是由于系统缺少字体导致的, /usr/share/fonts/  Centos默认存放字体的 ...

  3. 蓝桥杯 算法训练 ALGO-93 反置数

    算法训练 反置数   时间限制:1.0s   内存限制:512.0MB 问题描述 一个整数的“反置数”指的是把该整数的每一位数字的顺序颠倒过来所得到的另一个整数.如果一个整数的末尾是以0结尾,那么在它 ...

  4. SpringMVC解决跨域问题及CROS

    CORS 首先因为最近在做一个前后端分离的项目,分开就意味着可能不在一个域中,所以不可避免的遇到CORS的问题.试过几个方法: Spring MVC 4.2.5以后新增的支持跨域的注解@CrossOr ...

  5. 谷歌浏览器无法播放QQ空间视频动画的解决方案

    https://qzonestyle.gtimg.cn/qzone/photo/v7/js/module/flashDetector/flash_tutorial.pdf Chrome开启⽅法 1. ...

  6. vue-cli脚手架build目录下utils.js工具配置文件详解

    此文章用来解释vue-cli脚手架build目录中的utils.js配置文件 此配置文件是vue开发环境的wepack相关配置文件,主要用来处理css-loader和vue-style-loader ...

  7. 取当前时间,格式为,yyyy-mm-dd hh:mm:ss

    function CurentTime() { var now = new Date(); var year = now.getFullYear(); //年 var month = now.getM ...

  8. leetcode392

    public class Solution { public bool IsSubsequence(string s, string t) { ; ; while (i < s.Length & ...

  9. redis-win7

    http://blog.csdn.net/renfufei/article/details/38474435

  10. SqlServer数据导入到ORACLE

    ORACLE中执行 select * from SYSTEM."employ_epl"