图片变换 矩阵 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;@Overrideprotected 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_2Log.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.0canvas.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.0Log.i("bqt", matrixValues[Matrix.MTRANS_X] + "--" + matrixValues[Matrix.MTRANS_Y]);//144.0--0.0canvas.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.0canvas.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.0Log.i("bqt", matrixValues[Matrix.MTRANS_X] + "--" + matrixValues[Matrix.MTRANS_Y]);//144.0--0.0canvas.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" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:gravity="center_horizontal"android:orientation="horizontal" ><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="copy"android:text="复制" /><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="zoom"android:text="缩放" /><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="rotate"android:text="旋转" /><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="skew"android:text="错切" /><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="mirror"android:text="镜面" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:orientation="horizontal" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="画布横向缩放倍数"android:textSize="13sp" /><EditTextandroid: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" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="画布纵向缩放倍数"android:textSize="13sp" /><EditTextandroid: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><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:orientation="horizontal" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="图片横向缩放倍数"android:textSize="13sp" /><EditTextandroid: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" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="图片纵向缩放倍数"android:textSize="13sp" /><EditTextandroid: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><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:orientation="horizontal" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="中心旋转角度"android:textSize="13sp" /><EditTextandroid: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" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="错切相对值"android:textSize="13sp" /><EditTextandroid: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" /><EditTextandroid: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><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:orientation="horizontal" ><ImageViewandroid:id="@+id/iv_old"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#0000ff"android:src="@drawable/icon" /><ImageViewandroid: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的更多相关文章
- 图片变换【Matrix】矩阵 简介
Matrix矩阵介绍 官方文档地址:https://developer.android.com/reference/android/graphics/Matrix.html 在Android中,对图片 ...
- android图片缩小和放大Matrix
/**Bitmap放大的方法*/ private static Bitmap big(Bitmap bitmap) { Matrix matrix = new Matrix(); matrix.pos ...
- Android图片加载框架最全解析(五),Glide强大的图片变换功能
大家好,又到了学习Glide的时间了.前段时间由于项目开发紧张,再加上后来又生病了,所以停更了一个月,不过现在终于又可以恢复正常更新了.今天是这个系列的第五篇文章,在前面四篇文章的当中,我们已经学习了 ...
- OpenGL投影矩阵(Projection Matrix)构造方法
(翻译,图片也来自原文) 一.概述 绝大部分计算机的显示器是二维的(a 2D surface).在OpenGL中一个3D场景需要被投影到屏幕上成为一个2D图像(image).这称为投影变换(参见这或这 ...
- Android图片缓存之Bitmap详解
前言: 最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap.BitmapFactory这两个类. 图片缓存相关博客地址: Android图片缓 ...
- Android 图片旋转(使用Matrix.setRotate方法)
imageView2 = (ImageView) findViewById(R.id.img2); Bitmap bitmap = BitmapFactory.decodeResource(getRe ...
- 【Math for ML】矩阵分解(Matrix Decompositions) (下)
[Math for ML]矩阵分解(Matrix Decompositions) (上) I. 奇异值分解(Singular Value Decomposition) 1. 定义 Singular V ...
- 【Math for ML】矩阵分解(Matrix Decompositions) (上)
I. 行列式(Determinants)和迹(Trace) 1. 行列式(Determinants) 为避免和绝对值符号混淆,本文一般使用\(det(A)\)来表示矩阵\(A\)的行列式.另外这里的\ ...
- Android图片缓存之Bitmap详解(一)
前言: 最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap.BitmapFactory这两个类. Bitmap: Bitmap是Android ...
随机推荐
- Python 快捷键
Ctrl + [ .Ctrl + ] 缩进代码Alt+3 Alt+4 注释.取消注释代码行Alt+5 Alt+6 切换缩进方式 空格<=>TabAlt+/ 单词完成,只要文中出现过,就可以 ...
- protocol buffer介绍(protobuf)
一.理论概述0.参考资料入门资料:https://developers.google.com/protocol-buffers/docs/javatutorial更详细的资料:For more det ...
- JGraph
php中JPGraph入门配置与应用 什么是PHP JPGraph?专门提供图表的类库.它使得作图变成了一件非常简单的事情.生成非美工人士生成的图表.二维码算法. 到官方网站下载.docportal ...
- iOS开发——C篇&文件操作
今天开始C语言中的重点难点就基本上技术忘了,但是还有最后一个知识点不得不提,那就是文件操作. 我们都知道,我们每天都在使用电脑,手机,或者其他电子或者移动设备,其实我们在使用的时候每时每刻都在执行文件 ...
- 一条带分页的sql
SELECT * FROM (SELECT USERID, TYPE, TYPE_DESC, SEX, USERNAME, HEADPORTRAIT, HOSPITAL, HLEVEL, DEPT, ...
- [51单片机]18B20驱动函数
/**********DS18B20.h**********/ #include "REG52.H" #include "INTRINS.H" sbit DQ ...
- RMAN-06023: no backup or copy of datafile 6 found to restore
一:问题描述 我用指定备份集恢复时,报错: RMAN> run { 2> shutdown immediate; 3> startup mount; 4> allocate c ...
- pm2 安装使用
pm2 是全新开发的进程守护服务, 同时集成了负载均衡功能. 以及开机启动, 自动重启有问题进程. 还可以查看各服务进程状态. 使用方法参照:https://github.com/Unitech/pm ...
- I2C的读写操作实验
[实验任务] 利用24C08断电以后存储的数据不消失的特点,可以做一个断电保护装置.首先利用单片机做一个0-99秒的自动计时器.然后随机关断电源,在 通电以后计时器接着断电前的状态继续计时. [实 ...
- 用MarkDown来排版写作
Latex排版系统太复杂,MD很好用,微软开源了一套Madoko的开源在线MD编辑器,它提供了一台MD扩展,可以生成PDF(中间先生成Tex,再生成的PDF),幻灯片还有html.非常方便.写作,写p ...
