Android绘图之Matrix
一、概述
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.平移
- matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());
2.缩放
- matrix.setScale(2f, 2f);
3.旋转
- //第一种方式
- //旋转 围绕图片中心
- matrix.setRotate(45f,view.getImageBitmap().getWidth()/2f,view.getImageBitmap().getHeight()/2f);
- //平移
- matrix.postTranslate(view.getImageBitmap().getWidth()*1.5f,0f);
- //第二种方式
- //旋转 中心点(0,0)
- matrix.setRotate(45f);
- //先将图片中心移到(0,0),旋转后再移到原位置
- matrix.preTranslate(-view.getImageBitmap().getWidth()/2f,-view.getImageBitmap().getHeight()/2f);
- matrix.postTranslate(view.getImageBitmap().getWidth()*2f,view.getImageBitmap().getHeight()/2f);
4.错切
- matrix.setSkew(0.5f,0f);//水平
- matrix.setSkew(0f,0.5f);//竖直
- matrix.setSkew(0.5f,0.5f);//水平和数值
5.对称
1)x轴对称
- float matrix_values[] = {1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);
2)Y轴对称
- float matrix_values[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);
3)y=x对称
- float matrix_values[] = {0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);
三、代码
1.xml文件
- <?xml version="1.0" encoding="utf-8"?>
- <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@+id/rl"
- >
- <com.example.dhj.bitmapdemo.TransformMatrixView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@+id/view"
- />
- </RelativeLayout>
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="visible"
- >
- <Button
- android:id="@+id/button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"
- android:layout_marginBottom="135dp"
- android:onClick="click"
- android:text="平移" />
- <Button
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBaseline="@+id/button"
- android:layout_alignBottom="@+id/button"
- android:layout_marginLeft="17dp"
- android:layout_marginStart="17dp"
- android:layout_toEndOf="@+id/button"
- android:layout_toRightOf="@+id/button"
- android:onClick="click"
- android:text="旋转" />
- <Button
- android:id="@+id/button3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBottom="@+id/button2"
- android:layout_marginLeft="35dp"
- android:layout_marginStart="35dp"
- android:layout_toEndOf="@+id/button2"
- android:layout_toRightOf="@+id/button2"
- android:onClick="click"
- android:text="水平倾斜" />
- <Button
- android:id="@+id/button4"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBaseline="@+id/button5"
- android:layout_alignBottom="@+id/button5"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"
- android:onClick="click"
- android:text="竖直倾斜" />
- <Button
- android:id="@+id/button5"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignLeft="@+id/button2"
- android:layout_alignStart="@+id/button2"
- android:layout_below="@+id/button2"
- android:onClick="click"
- android:text="水平竖直倾斜" />
- <Button
- android:id="@+id/button6"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignLeft="@+id/button3"
- android:layout_alignStart="@+id/button3"
- android:layout_below="@+id/button3"
- android:onClick="click"
- android:text="x轴对称" />
- <Button
- android:id="@+id/button7"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"
- android:layout_below="@+id/button4"
- android:layout_marginTop="15dp"
- android:onClick="click"
- android:text="y轴对称" />
- <Button
- android:id="@+id/button8"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBottom="@+id/button7"
- android:layout_alignLeft="@+id/button5"
- android:layout_alignStart="@+id/button5"
- android:onClick="click"
- android:text="y=x对称" />
- <Button
- android:id="@+id/button11"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignLeft="@+id/button6"
- android:layout_alignStart="@+id/button6"
- android:layout_alignTop="@+id/button8"
- android:onClick="click"
- android:text="缩放" />
- </RelativeLayout>
- </FrameLayout>
2.自定义view
- class TransformMatrixView extends ImageView
- {
- private Bitmap bitmap;
- private Matrix matrix;
- public TransformMatrixView(Context context)
- {
- super(context);
- Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.p1);
- bitmap=resizeBitmap(b,162,251);
- matrix = new Matrix();
- setBackgroundColor(Color.parseColor("#3f51b5"));
- }
- public TransformMatrixView(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.p1);
- bitmap=resizeBitmap(b,162,251);
- matrix = new Matrix();
- // setBackgroundColor(Color.parseColor("#3f51b5"));
- }
- @Override
- protected void onDraw(Canvas canvas)
- {
- // 画出原图像
- canvas.drawBitmap(bitmap, 0, 0, null);
- // 画出变换后的图像
- canvas.drawBitmap(bitmap, matrix, null);
- super.onDraw(canvas);
- }
- @Override
- public void setImageMatrix(Matrix matrix)
- {
- this.matrix.set(matrix);
- super.setImageMatrix(matrix);
- }
- public Bitmap getImageBitmap()
- {
- return bitmap;
- }
- /**
- * 使用Matrix将Bitmap压缩到指定大小
- * @param bitmap
- * @param w
- * @param h
- * @return
- */
- public static Bitmap resizeBitmap(Bitmap bitmap, int w, int h)
- {
- int width = bitmap.getWidth();
- int height = bitmap.getHeight();
- float scaleWidth = ((float) w) / width;
- float scaleHeight = ((float) h) / height;
- Matrix matrix = new Matrix();
- matrix.postScale(scaleWidth, scaleHeight);
- Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width,
- height, matrix, true);
- return resizedBitmap;
- }
- }
3.activity
- public class MainActivity extends Activity {
- private TransformMatrixView view;
- Matrix matrix= new Matrix();
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_main);
- view= (TransformMatrixView) findViewById(R.id.view);
- }
- public void click(View v){
- switch (v.getId()){
- case R.id.button:
- tranlate();
- break;
- case R.id.button2:
- rorate();
- break;
- case R.id.button3:
- skewhorizontal();
- break;
- case R.id.button4:
- skewVertical();
- break;
- case R.id.button5:
- skew();
- break;
- case R.id.button6:
- symmetryHorizontal();
- break;
- case R.id.button7:
- symmetryVertical();
- break;
- case R.id.button8:
- symmetry();
- break;
- case R.id.button11:
- scale();
- break;
- }
- view.setImageMatrix(matrix);
- // view.invalidate();
- }
- //平移
- private void tranlate(){
- // 输出图像的宽度和高度(162 x 251)
- // Log.e("TestTransformMatrixActivity", "image size: width x height = " + view.getImageBitmap().getWidth() + " x " + view.getImageBitmap().getHeight());
- // 1. 平移
- matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());
- // 在x方向平移view.getImageBitmap().getWidth(),在y轴方向view.getImageBitmap().getHeight()
- }
- //旋转
- private void rorate(){
- //第一种方式
- //旋转 围绕图片中心
- matrix.setRotate(45f,view.getImageBitmap().getWidth()/2f,view.getImageBitmap().getHeight()/2f);
- //平移
- matrix.postTranslate(view.getImageBitmap().getWidth()*1.5f,0f);
- //第二种方式
- //旋转 中心点(0,0)
- matrix.setRotate(45f);
- //先将图片中心移到(0,0),旋转后再移到原位置
- matrix.preTranslate(-view.getImageBitmap().getWidth()/2f,-view.getImageBitmap().getHeight()/2f);
- matrix.postTranslate(view.getImageBitmap().getWidth()*2f,view.getImageBitmap().getHeight()/2f);
- }
- //缩放
- private void scale(){
- matrix.setScale(2f, 2f);
- matrix.postTranslate(view.getImageBitmap().getWidth(),view.getImageBitmap().getHeight());
- }
- //水平 倾斜
- private void skewhorizontal(){
- // matrix.setSkew(0.5f, 0f);
- // matrix.postTranslate(view.getImageBitmap().getWidth(), 0f);
- matrix.setSkew(0.5f,0f);
- matrix.postTranslate(view.getImageBitmap().getWidth(),0f);
- }
- //竖直 倾斜
- private void skewVertical(){
- matrix.setSkew(0f,0.5f);
- matrix.postTranslate(view.getImageBitmap().getWidth(),0f);
- }
- //倾斜 水平和竖直
- private void skew(){
- matrix.setSkew(0.5f,0.5f);
- matrix.postTranslate(view.getImageBitmap().getWidth(),0f);
- }
- //x轴对称
- private void symmetryHorizontal(){
- float matrix_values[] = {1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};
- matrix.setValues(matrix_values);
- matrix.postTranslate(0f,view.getImageBitmap().getHeight()*2);
- }
- //y轴对称
- private void symmetryVertical(){
- float matrix_values[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};
- matrix.setValues(matrix_values);
- matrix.postTranslate(view.getImageBitmap().getWidth()*2,0f);
- }
- //对称 y=x
- private void symmetry(){
- float matrix_values[] = {0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f};
- matrix.setValues(matrix_values);
- matrix.postTranslate(view.getImageBitmap().getWidth()+view.getImageBitmap().getHeight(),
- view.getImageBitmap().getHeight()+view.getImageBitmap().getWidth());
- }
- }
四、效果
参考:
Android中图像变换Matrix的原理、代码验证和应用
Android绘图之Matrix的更多相关文章
- 论文第5章:Android绘图平台的实现
面向移动设备的矢量绘图平台设计与实现 Design and Implementation of Mobile Device-oriented Vector Drawing Platform 引用本论文 ...
- Android群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧
第六章 Android绘图机制与处理技巧 1.屏幕尺寸信息屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DP ...
- 第三章 Android绘图机制与处理技巧
1.屏幕尺寸信息 屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DPI(Dots Per Inch),它是对 ...
- Android群英传笔记——第六章:Android绘图机制与处理技巧
Android群英传笔记--第六章:Android绘图机制与处理技巧 一直在情调,时间都是可以自己调节的,不然世界上哪有这么多牛X的人 今天就开始读第六章了,算日子也刚好一个月了,一个月就读一半,这效 ...
- Android为TV端助力 转载:Android绘图Canvas十八般武器之Shader详解及实战篇(下)
LinearGradient 线性渐变渲染器 LinearGradient中文翻译过来就是线性渐变的意思.线性渐变通俗来讲就是给起点设置一个颜色值如#faf84d,终点设置一个颜色值如#CC423C, ...
- Android中图像变换Matrix的原理、代码验证和应用(一)
第一部分 Matrix的数学原理 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类.Android中的Matrix是一个3 x 3的矩阵,其内容如下: Matri ...
- android 绘图之Canvas,Paint类
Canvas,Paint 1.在android 绘图但中经常要用到Canvas和Paint类,Canvas好比是一张画布,上面已经有你想绘制图画的轮廓了,而Paint就好比是画笔,就要给Canvas进 ...
- Android绘图机制(四)——使用HelloCharts开源框架搭建一系列炫酷图表,柱形图,折线图,饼状图和动画特效,抽丝剥茧带你认识图表之美
Android绘图机制(四)--使用HelloCharts开源框架搭建一系列炫酷图表,柱形图,折线图,饼状图和动画特效,抽丝剥茧带你认识图表之美 这里为什么不继续把自定义View写下去呢,因为最近项目 ...
- Android绘图机制(三)——自定义View的实现方式以及半弧圆新控件
Android绘图机制(三)--自定义View的三种实现方式以及实战项目操作 在Android绘图机制(一)--自定义View的基础属性和方法 里说过,实现自定义View有三种方式,分别是 1.对现有 ...
随机推荐
- datasnap 上传/下载大文件(本Demo以图传片文件为例)
好久没写技术文了 datasnap传大流. 完整代码,同时感谢叶兄传流的指点,(只公开十天) 附:下面代码,转载请注明出处 ::code 服务端: function TServerMethods1.D ...
- 搭建Ganglia乱码及其他问题总汇
搭建Ganglia乱码及其他问题 搭建完Ganglia监控后图像显示正常,但是文字却显示都是小方框,最后确定是由于系统缺少字体导致的, /usr/share/fonts/ Centos默认存放字体的 ...
- 蓝桥杯 算法训练 ALGO-93 反置数
算法训练 反置数 时间限制:1.0s 内存限制:512.0MB 问题描述 一个整数的“反置数”指的是把该整数的每一位数字的顺序颠倒过来所得到的另一个整数.如果一个整数的末尾是以0结尾,那么在它 ...
- SpringMVC解决跨域问题及CROS
CORS 首先因为最近在做一个前后端分离的项目,分开就意味着可能不在一个域中,所以不可避免的遇到CORS的问题.试过几个方法: Spring MVC 4.2.5以后新增的支持跨域的注解@CrossOr ...
- 谷歌浏览器无法播放QQ空间视频动画的解决方案
https://qzonestyle.gtimg.cn/qzone/photo/v7/js/module/flashDetector/flash_tutorial.pdf Chrome开启⽅法 1. ...
- vue-cli脚手架build目录下utils.js工具配置文件详解
此文章用来解释vue-cli脚手架build目录中的utils.js配置文件 此配置文件是vue开发环境的wepack相关配置文件,主要用来处理css-loader和vue-style-loader ...
- 取当前时间,格式为,yyyy-mm-dd hh:mm:ss
function CurentTime() { var now = new Date(); var year = now.getFullYear(); //年 var month = now.getM ...
- leetcode392
public class Solution { public bool IsSubsequence(string s, string t) { ; ; while (i < s.Length & ...
- redis-win7
http://blog.csdn.net/renfufei/article/details/38474435
- SqlServer数据导入到ORACLE
ORACLE中执行 select * from SYSTEM."employ_epl"