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基本上是差不 ...
随机推荐
- struts2.3.4.1转换成eclipse项目的过程
1.在本地安装配置maven. 1.1.从maven官网下载,官网地址:http://maven.apache.org/download.cgi 1.2.配置maven环境变量 例如,我的 ...
- Python基础学习之字符串(1)
字符串 由字符组成的序列,即字符串. 1.基本字符串操作 所有标准的序列操作(索引.切片.乘法.判断成员资格.求长度.取最小值和最大值)对字符串同样适用: >>> website=' ...
- git github添加远程仓库出错 remote origin already exists
在github上建立了仓库后,执行 git remote add origin https://github.com/zhangsan/sample.git时,提示 remote origin alr ...
- April 9 2017 Week 15 Sunday
In the evening one may praise the day. 入夜方能赞美白昼. I think that could be understand in different ways, ...
- leetcode: 树
1. sum-root-to-leaf-numbers Given a binary tree containing digits from0-9only, each root-to-leaf pat ...
- 关于安卓手机访问一些网站或者Fiori应用弹出安装证书的提示
有朋友问遇到在安卓手机上安装Fiori Client,打开的时候提示需要安装证书,如下图所示: 我在自己的Android手机试了试,因为我没有装Fiori Client,所以就用手机浏览器直接访问ht ...
- IOS GCD (事例下载图片)
@interface HMViewController () @property (weak, nonatomic) IBOutlet UIImageView *imageView; @end @im ...
- 2017.9.26 request请求参数用法
4.2 访问请求参数 request对象的getParamter()方法,可以用来获取用户(客户端)提交的数据 4.2.1 访问请求参数的方法 String 自符串变量 =request.getPar ...
- git优点缺点(简单介绍)
什么是Git Git是目前世界上最先进的分布式版本控制系统. Git是免费.开源的 最初Git是为辅助 Linux 内核开发的,来替代 BitKeeper 作者 Linux和Git之父李纳斯·托沃兹( ...
- HTTP head meta
HTTP(HyperTextTransferProtocol)即超文本传输协议,目前网页传输的的通用协议.HTTP协议采用了请求/响应模型,浏览器或其他客户端发出请求,服务器给与响应.就整个网络资源传 ...