承香墨影 Android--Matrix图片变换处理

承香墨影

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 }

  

  源码下载

时间: 2024-10-05 18:09:05

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

Android Matrix图像变换处理

Canvas类中drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)方法中有个参数类型是Matrix,从字面上理解是矩阵的意思,而实际上它也确实是个3x3的矩阵.Matrix在Android中的主要作用是图像变换,如平移.旋转.缩放.扭曲等. 关于图像如何通过矩阵进行变化可参考这篇文章图像处理-关于像素坐标矩阵变换(平移,旋转,缩放,错切) Matrix内部通过维护一个float[9]的数组来构成3x3矩阵的形式,而实际上所有的变换方法说到底

浅谈android中图片处理之图形变换特效Matrix(四)

今天,我们就来谈下android中图片的变形的特效,在上讲博客中我们谈到android中图片中的色彩特效来实现的.改变它的颜色主要通过ColorMatrix类来实现. 现在今天所讲的图片变形的特效主要就是通过Matrix类来实现,我们通过上篇博客知道,改变色彩特效,主要是通过ColorMatrxi矩阵的系数,以及每个像素点上所对应的颜色偏移量.而今天的图形变换与那个也是非常的类似.它是一个3*3矩阵,而颜色矩阵则是一个4*5的矩阵.在这个3*3矩阵中则表述出了每个像素点的XY坐标信息.然后通过修

Android bitmap图片处理

一.View转换为Bitmap 在Android中所有的控件都是View的直接子类或者间接子类,通过它们可以组成丰富的UI界面.在窗口显示的时候Android会把这些控件都加载到内存中,形成一个以ViewRoot为根节点的控件树,然后由根节点开始逐级把控件绘制到屏幕上. 可以通过调用控件的setDrawingCacheEnabled(true)方法,开启绘图缓存功能,在绘制View的时候把图像缓存起来,然后通过getDrawingCache()方法获取这个缓存的Bitmap.需要注意的是,当不再

Android Matrix(转)

Matrix的数学原理 平移变换 旋转变换 缩放变换 错切变换 对称变换 代码验证 Matrix的数学原理 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类.Android中的Matrix是一个3 x 3的矩阵,其内容如下: Matrix的对图像的处理可分为四类基本变换: Translate           平移变换 Rotate                旋转变换 Scale                  缩放变换 Skew          

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

在开发Android企业应用时,会经常上传图片到服务器,而我们公司目前维护的一个项目便是如此.该项目是通过私有apn与服务器进行交互的,联通的还好,但移动的速度实在太慢,客户在使用软件的过程中,由于上传的信息中可能包含多张图片,会经常出现上传图片失败的问题,为了解决这个问题,我们决定把照片压缩到100k以下,并且保证图片不失真(目前图片经过压缩后,大约300k左右).于是我就重新研究了一下Android的图片压缩技术. Android端目录结构如下图所示: 使用的第三方库jar包,如下图所示:

Android 设置图片倒影效果

首先,贴出效果图: 1.布局文件main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_p

Android 相册图片选取+自定义裁剪方式(非系统裁剪)

不多说,直接上代码(裁剪的代码摘自网络.)(项目可运行) 主要是系统自身的剪切方式在有些机型上会程序崩溃的问题. 1 package com.jichun.activity; 2 3 import java.io.FileNotFoundException; 4 5 import com.jichun.view.CropCanvas; 6 7 import android.app.Activity; 8 import android.content.ContentResolver; 9 impo

Android浏览图片,点击放大至全屏效果

最近做一个项目类似于QQ空间,做到照片浏览的功能,对于QQ空间中点击图片放大至全屏,感觉效果很赞,于是也做了个类似的效果.如下. 我不知道QQ那个是怎么做的,我的思路如下: 首先,从图片缩略界面跳转到图片详情页面,应该是从一个Activity跳转到另外一个Activity,应该图片详情页面也有很多操作,用View或者Dialog不是很好.所以现在难点就是,如何使得前一个界面的ImageView在另外一个界面做缩放切割动画. 一般缩略界面的ImageView的是如上图所示的正方形的,并且是CENT

Android Matrix类以及ColorMatri

引自:http://www.chinabaike.com/t/37396/2014/0624/2556217.html Android Matrix类以及ColorMatrix类详解 最近在系统学习了android的图像处理(在网上搜集了一些资料并自己编写了测试程序,做了整理),现在这里做一总结: 一.ColorMatrix类 ColorMatrix是一个5x4阶的矩阵 在下面表示为A,第一行表示R红色分量,第二行表示G绿色分量,第三行表示B蓝色分量,第四行表示透明度: 用一维数组的存储方式如下