Android学习记录(9)—Android之Matrix的用法
Matrix ,中文里叫矩阵,高等数学里有介绍,在图像处理方面,主要是用于平面的缩放、平移、旋转等操作。
首先介绍一下矩阵运算。加法和减法就不用说了,对应位相加就好。图像处理,主要用到的是乘法 。下面是一个乘法的公式:
在 Android 里面, Matrix 由 9 个 float 值构成,是一个 3*3 的矩阵。如下图:
解释一下,上面的sinX 和cosX ,表示旋转角度的cos 值和sin值,注意,旋转角度是按顺时针方向计算的。 translateX 和 translateY 表示 x 和 y 的平移量。 scale 是缩放的比例, 1 是不变, 2 是表示缩放 1/2 。
Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。
set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。
post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。例如,要将一个图片旋转30度,然后平移到(100,100)的地方,那么可以这样做:Matrix m = new Matrix(); m.postRotate(30 ); m.postTranslate(100 , 100 ); 这样就达到了想要的效果。
pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。例如上面的例子,如果用pre的话,就要这样:Matrix m = new Matrix(); m.setTranslate(100 , 100 ); m.preRotate(30 );
旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,默认情况下,是围绕(0,0)点来进行。
特别注意:
Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在
Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。
set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。
post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。
镜面效果:
倒影效果:
图片的合成(水印):
不多说了,直接上代码了。
MainActivity.java里的主要代码如下:
package net.loonggg.testmatrix; import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.os.Bundle;
import android.view.Window;
import android.widget.ImageView; public class MainActivity extends Activity {
private ImageView iv1, iv2;
private Canvas canvas;
private Paint paint; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
iv1 = (ImageView) findViewById(R.id.iv1);
iv2 = (ImageView) findViewById(R.id.iv2);
Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(),
R.drawable.weibo);
Bitmap updateBitmap = Bitmap.createBitmap(bitmap1.getWidth() * 2,
bitmap1.getHeight() * 2, bitmap1.getConfig());
canvas = new Canvas(updateBitmap);
paint = new Paint();
paint.setColor(Color.BLACK);
Matrix matrix = new Matrix();
// setMirrorOne(bitmap1, matrix);
// setInvertedImage(bitmap1, matrix);
// setBaseChange(matrix);
canvas.drawBitmap(bitmap1, matrix, paint);
setImageSynthesis(matrix);
iv1.setImageBitmap(bitmap1);
iv2.setImageBitmap(updateBitmap); } /**
* 还有一些基本变化
*/
private void setBaseChange(Matrix matrix) {
// matrix.setRotate(60);// 这是旋转多少度
// matrix.setRotate(degrees, px, py);//这个方法是以哪个点为中心进行旋转多少度
// matrix.setSkew(kx, ky);//设置倾斜,以x轴倾斜,还是y轴
// 倾斜x和y轴,以(100,100)为中心。
// matrix.postSkew(0 .2f, 0 .2f, 100 , 100 );
// matrix.setScale(0.5f, 1);//缩放宽度变为原来的一半,高度不变
} /**
* 设置倒影效果
*
* @param bitmap1
* @param matrix
*/
private void setInvertedImage(Bitmap bitmap1, Matrix matrix) {
matrix.setScale(1, -1);
matrix.postTranslate(0, bitmap1.getHeight());
} /**
* 设置镜面效果方法一
*
* @param bitmap1
* @param matrix
*/
private void setMirrorOne(Bitmap bitmap1, Matrix matrix) {
matrix.setTranslate(bitmap1.getWidth(), 0);// 这个是移动
matrix.preScale(-1, 1);
} // ---------------------------------------------------------
/**
* 解释:镜面效果方法一和二的区别:
* 不知道大家看没看出来,其实这两种方法的效果是一样的,只不过是设置步骤不一样,post是后乘,当前的矩阵乘以参数给出的矩阵
* 。可以连续多次使用post,来完成所需的整个变换。 pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。
* 可以连续多次使用post
* ,来完成所需的整个变换,但是不可以连续使用set来完成矩阵的整个变换,为什么呢?set是直接设置Matrix的值,每次set一次
* ,整个Matrix的数组都会变掉,第一次可以使用set,之后的变换必须换成post或者pre,也可以一直用post也行
*/
// --------------------------------------------------------- /**
* 设置镜面效果方法二
*
* @param bitmap1
* @param matrix
*/
private void setMirrorTwo(Bitmap bitmap1, Matrix matrix) {
matrix.setScale(-1, 1);
matrix.postTranslate(bitmap1.getWidth(), 0);
} /**
* 设置图片的合成
*
* @param matrix
*/
private void setImageSynthesis(Matrix matrix) {
Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
// 设置图片合成时的各种模式
paint.setXfermode(new PorterDuffXfermode(Mode.DARKEN));
// 图片的合成很简单,就是再以bitmap2为基图往目标图片上画一次
canvas.drawBitmap(bitmap2, matrix, paint);
} }
布局文件的代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" > <ImageView
android:id="@+id/iv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> <ImageView
android:id="@+id/iv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> </LinearLayout>
转载请注明出处:http://blog.csdn.net/loongggdroid/article/details/18706999
Android学习记录(9)—Android之Matrix的用法的更多相关文章
- Android学习记录(3)—Android中ContentProvider的基本原理学习总结
一.ContentProvider简介 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.虽然使用其他方法也可以对外共享数据 ...
- 【Android学习入门】Android studio基本设置
1.背景设置 依次选择File->Settings-->Appearance & Behaviour->Apprearance,然后勾选 show line number. ...
- ElasticSearch 学习记录之ES短语匹配基本用法
短语匹配 短语匹配故名思意就是对分词后的短语就是匹配,而不是仅仅对单独的单词进行匹配 下面就是根据下面的脚本例子来看整个短语匹配的有哪些作用和优点 GET /my_index/my_type/_sea ...
- mono for android 学习记录
C#开发Android应用实战(全 扫描 中文版) 学习记录: 拖完控件后,不要急着按F5,需要重新生成,才能自动修改 Resource.Designer.cs 文件 1. Activity 是基于a ...
- 【Android】Android 学习记录贴
官网 教程学习笔记 Genymotion 安卓虚拟器太慢,用Genymotion(装载eclipse的插件) 利用Genymotion运行Android应用程序 1.首先,点击 来启动或者创建您要使用 ...
- android 学习记录-----------android 活动 意图 碎片
将此篇博客作为记录android项目开发过程中的学习记录
- Android学习记录:界面设计
本片文章将记录进行android界面开发时积累的知识 包括 activity全屏 activity跳转 button设计 逐个输入编辑框设计 d0710 合并旧文章总结更新 d0721 添加内容 == ...
- Android学习记录(10)—Android之图片颜色处理
你想做到跟美图秀秀一样可以处理自己的照片,美化自己的照片吗?其实你也可以自己做一个这样的软件,废话不多说了,直接上图,上代码了! 效果图如下: 没处理前: 处理之后: MainActivity.jav ...
- Android学习记录(6)—将java中的多线程下载移植到Android中(即多线程下载在Android中的使用)③
在这一节中,我们就来讲多线程下载以及断点续传在android中怎么使用,前两节是为本节做准备的,没有看前两节的同学,最好看完前面的两篇文章再来看这篇.其实在android端的应用和java基本上是差不 ...
随机推荐
- 如何查看某个用户指定时间段的ABAP开发记录
输入用户名和想查询的时间段: 执行得到结果.双击可查看具体代码: 工具源代码: REPORT tool_dev_history. PARAMETERS: name TYPE usr02-bname O ...
- 【CCPC-Wannafly Winter Camp Day3 (Div1) F】小清新数论(莫比乌斯反演+杜教筛)
点此看题面 大致题意: 让你求出\(\sum_{i=1}^n\sum_{j=1}^n\mu(gcd(i,j))\). 莫比乌斯反演 这种题目,一看就是莫比乌斯反演啊!(连莫比乌斯函数都有) 关于莫比乌 ...
- 2017.11.4 JavaWeb-----基于JavaBean+JSP求任意两数代数和(改进的在JSP页面中无JSP脚本代码的)+网页计数器JavaBean的设计与使用
修改后的JSP中不含有JSP脚本代码这使得JSP程序的清晰性.简单 1.设计JavaBean 的Add.java 类 package beans; public class Add { private ...
- memcache 基本操作
输入 telnet localhost 11211 步骤: 1.输入 set hans 0 0 3 回车 2. 输入 123 回车 3. get hans 回车 删除操作,输入 delete h ...
- c#转载的
C#做项目时的一些经验分享 1.对于公用的类型定义,要单独抽取出来,放到单独的DLL中. 2.通过大量定义interface接口,来提高模块化程度,不同功能之间通过实现接口来面向接口编程. 3.如果项 ...
- VisualSVN 4.0.10 破解版 附上破解过程
VisualSVN一般情况下使用不需要破解,可以直接使用社区授权.但是社区授权不支持域用户. 如果要再域下面使用就需要破解了. 原版的VisualSVN和破解后的DLL已打包上传(仅供学习使用) 破解 ...
- C# foreach语句
一.C# foreach语句 foreach语句能够对实现Ienumerable接口的容器进行遍历,并提供一个枚举器来实现Ienumerable接口.foreach语句为数组或对象集合中的各个元素执行 ...
- 阅读detection
关于detecion的几篇文章,感觉有必要系统学习一下,并记录一下了,最近看书比较多,文章看得少,赶紧看看吧. FPN:Feature Pyramid Networks for Object Dete ...
- Map the Debris -freecodecamp算法题目
Map the Debris 1.要求 返回一个数组,其内容是把原数组中对应元素的平均海拔转换成其对应的轨道周期. 原数组中会包含格式化的对象内容,像这样 {name: 'name', avgAlt: ...
- datatable设置动态宽度,超过一定长度出现滚动条
获得宽度:var tableAutoWidth = $('.dataTable_wrapper').width();if (tableAutoWidth < 1200) { tableAutoW ...