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>
activity_main.xml

  實現代碼:

  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 }
MainActivity.java

  

  源碼下載

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM