Android--Matrix图片变换处理

前言

  本篇博客主要讲解一下如何处理对一个Bitmap对象进行处理,包括:缩放、旋转、位移、倾斜等。在最后将以一个简单的Demo来演示图片特效的变换。

  本篇博客的主要内容:

  1. Matrix
  2. Matrix缩放
  3. Matrix旋转
  4. Matrix位移
  5. Matrix倾斜
  6. Matrix变换注意事项
  7. Matrix完整的Demo

Matrix

  对于一个图片变换的处理,需要Matrix类的支持,它位于"android.graphics.Matrix"包下,是Android提供的一个矩阵工具类,它本身不能对图像或View进行变换,但它可与其他API结合来控制图形、View的变换,如Canvas。

  Matrix提供了一些方法来控制图片变换:

  • setTranslate(float dx,float dy):控制Matrix进行位移。
  • 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进行depress角度的旋转,轴心为(0,0)。
  • setRotate(float degrees,float px,float py):控制Matrix进行depress角度的旋转,轴心为(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方向上的缩放比例。

  之前有提过,图片在内存中存放的就是一个一个的像素点,而对于图片的变换主要是处理图片的每个像素点,对每个像素点进行相应的变换,即可完成对图像的变换。上面已经列举了Matrix进行变换的常用方法,下面以几个Demo来讲解一下如何通过Matrix进行变换。

Matrix缩放

  代码:

 1     /**
2 * 缩放图片
3 */
4 protected void bitmapScale(float x, float y) {
5 // 因为要将图片放大,所以要根据放大的尺寸重新创建Bitmap
6 Bitmap afterBitmap = Bitmap.createBitmap(
7 (int) (baseBitmap.getWidth() * x),
8 (int) (baseBitmap.getHeight() * y), baseBitmap.getConfig());
9 Canvas canvas = new Canvas(afterBitmap);
10 // 初始化Matrix对象
11 Matrix matrix = new Matrix();
12 // 根据传入的参数设置缩放比例
13 matrix.setScale(x, y);
14 // 根据缩放比例,把图片draw到Canvas上
15 canvas.drawBitmap(baseBitmap, matrix,paint);
16 iv_after.setImageBitmap(afterBitmap);
17 }

  效果展示:

Matrix旋转

  代码:

 1     /**
2 * 图片旋转
3 */
4 protected void bitmapRotate(float degrees) {
5 // 创建一个和原图一样大小的图片
6 Bitmap afterBitmap = Bitmap.createBitmap(baseBitmap.getWidth(),
7 baseBitmap.getHeight(), baseBitmap.getConfig());
8 Canvas canvas = new Canvas(afterBitmap);
9 Matrix matrix = new Matrix();
10 // 根据原图的中心位置旋转
11 matrix.setRotate(degrees, baseBitmap.getWidth() / 2,
12 baseBitmap.getHeight() / 2);
13 canvas.drawBitmap(baseBitmap, matrix, paint);
14 iv_after.setImageBitmap(afterBitmap);
15 }

  效果展示:

Matrix位移

  代码:

 1     /**
2 * 图片移动
3 */
4 protected void bitmapTranslate(float dx, float dy) {
5 // 需要根据移动的距离来创建图片的拷贝图大小
6 Bitmap afterBitmap = Bitmap.createBitmap(
7 (int) (baseBitmap.getWidth() + dx),
8 (int) (baseBitmap.getHeight() + dy), baseBitmap.getConfig());
9 Canvas canvas = new Canvas(afterBitmap);
10 Matrix matrix = new Matrix();
11 // 设置移动的距离
12 matrix.setTranslate(dx, dy);
13 canvas.drawBitmap(baseBitmap, matrix, paint);
14 iv_after.setImageBitmap(afterBitmap);
15 }

  效果展示:

Matrix倾斜

  代码:

 1     /**
2 * 倾斜图片
3 */
4 protected void bitmapSkew(float dx, float dy) {
5 // 根据图片的倾斜比例,计算变换后图片的大小,
6 Bitmap afterBitmap = Bitmap.createBitmap(baseBitmap.getWidth()
7 + (int) (baseBitmap.getWidth() * dx), baseBitmap.getHeight()
8 + (int) (baseBitmap.getHeight() * dy), baseBitmap.getConfig());
9 Canvas canvas = new Canvas(afterBitmap);
10 Matrix matrix = new Matrix();
11 // 设置图片倾斜的比例
12 matrix.setSkew(dx, dy);
13 canvas.drawBitmap(baseBitmap, matrix, paint);
14 iv_after.setImageBitmap(afterBitmap);
15 }

  效果展示:

Matrix变换注意事项

  上面几个小方法演示了如何使用Matrix进行变换,但是还有几点需要额外注意一下:

  • 对于一个从BitmapFactory.decodeXxx()方法加载的Bitmap对象而言,它是一个只读的,无法对其进行处理,必须使用Bitmap.createBitmap()方法重新创建一个Bitmap对象的拷贝,才可以对拷贝的Bitmap进行处理。
  • 因为图像的变换是针对每一个像素点的,所以有些变换可能发生像素点的丢失,这里需要使用Paint.setAnitiAlias(boolean)设置来消除锯齿,这样图片变换后的效果会好很多。
  • 在重新创建一个Bitmap对象的拷贝的时候,需要注意它的宽高,如果设置不妥,很可能变换后的像素点已经移动到"图片之外"去了。

Matrix完整的Demo

  下面给出本篇博客讲解的使用Matrix的完整Demo代码。

  布局代码:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical"
6 android:paddingBottom="@dimen/activity_vertical_margin"
7 android:paddingLeft="@dimen/activity_horizontal_margin"
8 android:paddingRight="@dimen/activity_horizontal_margin"
9 android:paddingTop="@dimen/activity_vertical_margin"
10 tools:context=".MainActivity" >
11
12 <LinearLayout
13 android:layout_width="wrap_content"
14 android:layout_height="wrap_content"
15 android:orientation="horizontal" >
16
17 <Button
18 android:id="@+id/btn_scale"
19 android:layout_width="wrap_content"
20 android:layout_height="wrap_content"
21 android:text="缩放" />
22
23 <Button
24 android:id="@+id/btn_rotate"
25 android:layout_width="wrap_content"
26 android:layout_height="wrap_content"
27 android:text="旋转" />
28
29 <Button
30 android:id="@+id/btn_translate"
31 android:layout_width="wrap_content"
32 android:layout_height="wrap_content"
33 android:text="平移" />
34
35 <Button
36 android:id="@+id/btn_skew"
37 android:layout_width="wrap_content"
38 android:layout_height="wrap_content"
39 android:text="倾斜" />
40 </LinearLayout>
41 <!-- 原始图片 -->
42 <ImageView
43 android:id="@+id/iv_base"
44 android:layout_width="wrap_content"
45 android:layout_height="wrap_content" />
46 <!-- 处理之后的图片 -->
47 <ImageView
48 android:id="@+id/iv_after"
49 android:layout_width="wrap_content"
50 android:layout_height="wrap_content" />
51
52 </LinearLayout>

  实现代码:

  1 package cn.bgxt.canvasmatrixdemo;
2
3 import android.os.Bundle;
4 import android.view.View;
5 import android.widget.Button;
6 import android.widget.ImageView;
7 import android.app.Activity;
8 import android.graphics.Bitmap;
9 import android.graphics.BitmapFactory;
10 import android.graphics.Canvas;
11 import android.graphics.Matrix;
12 import android.graphics.Paint;
13
14 public class MainActivity extends Activity {
15 private Button btn_scale, btn_rotate, btn_translate, btn_skew;
16 private ImageView iv_base, iv_after;
17 private Bitmap baseBitmap;
18 private Paint paint;
19
20 @Override
21 protected void onCreate(Bundle savedInstanceState) {
22 super.onCreate(savedInstanceState);
23 setContentView(R.layout.activity_main);
24
25 btn_scale = (Button) findViewById(R.id.btn_scale);
26 btn_rotate = (Button) findViewById(R.id.btn_rotate);
27 btn_translate = (Button) findViewById(R.id.btn_translate);
28 btn_skew = (Button) findViewById(R.id.btn_skew);
29
30 btn_scale.setOnClickListener(click);
31 btn_rotate.setOnClickListener(click);
32 btn_translate.setOnClickListener(click);
33 btn_skew.setOnClickListener(click);
34
35 iv_base = (ImageView) findViewById(R.id.iv_base);
36 iv_after = (ImageView) findViewById(R.id.iv_after);
37
38 baseBitmap = BitmapFactory.decodeResource(getResources(),
39 R.drawable.ic_launcher);
40 iv_base.setImageBitmap(baseBitmap);
41
42 // 设置画笔,消除锯齿
43 paint = new Paint();
44 paint.setAntiAlias(true);
45 }
46
47 private View.OnClickListener click = new View.OnClickListener() {
48
49 @Override
50 public void onClick(View v) {
51
52 switch (v.getId()) {
53 case R.id.btn_scale:
54 bitmapScale(2.0f, 4.0f);
55 break;
56 case R.id.btn_rotate:
57 bitmapRotate(180);
58 break;
59 case R.id.btn_translate:
60 bitmapTranslate(20f, 20f);
61 break;
62 case R.id.btn_skew:
63 bitmapSkew(0.2f, 0.4f);
64 break;
65 default:
66 break;
67 }
68
69 }
70 };
71
72 /**
73 * 缩放图片
74 */
75 protected void bitmapScale(float x, float y) {
76 // 因为要将图片放大,所以要根据放大的尺寸重新创建Bitmap
77 Bitmap afterBitmap = Bitmap.createBitmap(
78 (int) (baseBitmap.getWidth() * x),
79 (int) (baseBitmap.getHeight() * y), baseBitmap.getConfig());
80 Canvas canvas = new Canvas(afterBitmap);
81 // 初始化Matrix对象
82 Matrix matrix = new Matrix();
83 // 根据传入的参数设置缩放比例
84 matrix.setScale(x, y);
85 // 根据缩放比例,把图片draw到Canvas上
86 canvas.drawBitmap(baseBitmap, matrix, paint);
87 iv_after.setImageBitmap(afterBitmap);
88 }
89
90 /**
91 * 倾斜图片
92 */
93 protected void bitmapSkew(float dx, float dy) {
94 // 根据图片的倾斜比例,计算变换后图片的大小,
95 Bitmap afterBitmap = Bitmap.createBitmap(baseBitmap.getWidth()
96 + (int) (baseBitmap.getWidth() * dx), baseBitmap.getHeight()
97 + (int) (baseBitmap.getHeight() * dy), baseBitmap.getConfig());
98 Canvas canvas = new Canvas(afterBitmap);
99 Matrix matrix = new Matrix();
100 // 设置图片倾斜的比例
101 matrix.setSkew(dx, dy);
102 canvas.drawBitmap(baseBitmap, matrix, paint);
103 iv_after.setImageBitmap(afterBitmap);
104 }
105
106 /**
107 * 图片移动
108 */
109 protected void bitmapTranslate(float dx, float dy) {
110 // 需要根据移动的距离来创建图片的拷贝图大小
111 Bitmap afterBitmap = Bitmap.createBitmap(
112 (int) (baseBitmap.getWidth() + dx),
113 (int) (baseBitmap.getHeight() + dy), baseBitmap.getConfig());
114 Canvas canvas = new Canvas(afterBitmap);
115 Matrix matrix = new Matrix();
116 // 设置移动的距离
117 matrix.setTranslate(dx, dy);
118 canvas.drawBitmap(baseBitmap, matrix, paint);
119 iv_after.setImageBitmap(afterBitmap);
120 }
121
122 /**
123 * 图片旋转
124 */
125 protected void bitmapRotate(float degrees) {
126 // 创建一个和原图一样大小的图片
127 Bitmap afterBitmap = Bitmap.createBitmap(baseBitmap.getWidth(),
128 baseBitmap.getHeight(), baseBitmap.getConfig());
129 Canvas canvas = new Canvas(afterBitmap);
130 Matrix matrix = new Matrix();
131 // 根据原图的中心位置旋转
132 matrix.setRotate(degrees, baseBitmap.getWidth() / 2,
133 baseBitmap.getHeight() / 2);
134 canvas.drawBitmap(baseBitmap, matrix, paint);
135 iv_after.setImageBitmap(afterBitmap);
136 }
137
138 }

  

  源码下载

承香墨影 Android--Matrix图片变换处理的更多相关文章

  1. Android bitmap图片处理

    一.View转换为Bitmap         在Android中所有的控件都是View的直接子类或者间接子类,通过它们可以组成丰富的UI界面.在窗口显示的时候Android会把这些控件都加载到内存中 ...

  2. Android Matrix(坐标矩阵)

    Android Matrix 2016-02-26 14:38:10 介绍 中文名:坐标矩阵 高等数学里有介绍,在图像处理方面,主要是用于平面的缩放.平移.旋转等操作. 在Android里面,Matr ...

  3. Android Matrix类以及ColorMatri

    引自:http://www.chinabaike.com/t/37396/2014/0624/2556217.html Android Matrix类以及ColorMatrix类详解 最近在系统学习了 ...

  4. android中图片倒影、圆角效果重绘

    本文用来记录一些Android 操作图片的方法,方便查看. 1.将Drawable转化为Bitmap public static Bitmap drawableToBitmap(Drawable dr ...

  5. Android压缩图片到100K以下并保持不失真的高效方法

    前言:目前一般手机的相机都能达到800万像素,像我的Galaxy Nexus才500万像素,拍摄的照片也有1.5M左右.这么大的照片上传到服务器,不仅浪费流量,同时还浪费时间. 在开发Android企 ...

  6. 仿优酷Android客户端图片左右滑动(自动滑动)

    最终效果: 页面布局main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayou ...

  7. 用ticons指令结合ImageMagickDisplay工具批量生成Android适应图片

    用ticons指令结合ImageMagickDisplay工具批量生成Android适应图片 ticons的用法可以百度 这里记录下具体的编译方法 在安装了ticons和ImageMagickDisp ...

  8. Android 实现图片画画板

    本文主要讲述了Android 实现图片画画板 设计项目布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk ...

  9. 关于Android中图片大小、内存占用与drawable文件夹关系的研究与分析

    原文:关于Android中图片大小.内存占用与drawable文件夹关系的研究与分析 相关: Android drawable微技巧,你所不知道的drawable的那些细节 经常会有朋友问我这个问题: ...

随机推荐

  1. Windows 下Apace tomcat

    java JDK安装: 1. 官方www.oracle.com 下载jdk 2. 环境变量配置 (1)新建->变量名:JAVA_HOME变量值:C:\Program Files (x86)\Ja ...

  2. 安卓第十一天笔记-Intent与inter-filter配置

    安卓第十一天笔记-Intent与inter-filter配置 Intent与inter-filter配置 1.Intent对象简述 Android应用中有包含三种重要组件:Activity,Servi ...

  3. 基础学习day03---程序结构与控制、函数与数组入门

    一.程序结构   1.顺序结构 2.选择结构 3.循环结构 二.顺序结构 程序至上而下逐行执行,一条语句执行完之后继续执行下一条语句,一直到程序的末尾 三.条件选择结构 选择结构是根据条件的成立与否, ...

  4. macbook pro 重装系统

    重装前系统版本:10.11.6 因为我在系统更新时强行关机,后来在编译代码的时候就一直有奇怪的错误,所以选择重装系统. 前提条件:一定要有网络 1.关机状态下按住command + r ,按一下开机键 ...

  5. iOS开发之网络编程--4、NSURLSessionDataTask实现文件下载(离线断点续传下载) <进度值显示优化>

    前言:根据前篇<iOS开发之网络编程--2.NSURLSessionDownloadTask文件下载>或者<iOS开发之网络编程--3.NSURLSessionDataTask实现文 ...

  6. 在MAC平台下使用Eclipse出现了中文乱码

    在Preference(偏好设置)中,搜索框中输入content找到Content Types,然后在text中找到并选中Java Source File, 然后在Defalut encoding输入 ...

  7. 配置gitlab gerrit jenkins

    配置gerrit 在gerrit创建jenkins用户 把jenkins用户加入Non-Interactive的组中 Projects -> List -> All-Projects Pr ...

  8. Effective Java 20 Prefer class hierarchies to tagged classes

    Disadvantage of tagged classes 1. Verbose (each instance has unnecessary irrelevant fields). 2. Erro ...

  9. Effective Java 63 Include failure-capture information in detail message

    Principle To capture the failure, the detail message of an exception should contain the values of al ...

  10. Javascript中substr和substring的区别

    由于在项目中有需要对字符串进行截取,然后手残使用了IDE自动提示的substr,没想那么多以为substr和substring没多大区别. 然而并不是,且听我一一道来. 1. substr(index ...