在Android中,項目目錄下的res\drawable用來放置該項目的圖片資源。
Android中提供了Bitmap類來擷取影像檔資訊,進行映像的平移、旋轉及縮放等操作,並可以指定格式儲存影像檔。
1.映像繪製
在繪製映像之前,需要從項目目錄下的res\drawable中擷取所需的圖片資源。我們可以通過資源索引來獲得該映像對象Bitmap。具體方法如下(在項目目錄下的res\drawable中放置了一張名為fuwa.png的圖片):
mBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.fuwa)).getBitmap():
其中,getResources()方法的作用是取得資來源物件;getDrawable()方法的作用取得資源中的Drawable對象,參數為資源索引id;getBitmap()方法的作用是得到Bitmap對象。
獲得映像資源後,可以使用drawBitmap()方法將映像顯示到螢幕的(x,y)座標位置上,具體方法如下:
Canvas.drawBitmap(mBitmap, x, y, null);
此外,要獲得映像的資訊,可以通過mBitmap.getHight()方法獲得該映像的高度,通過mBitmap.getWidth()f方法獲得該映像的寬度。
2.映像的平移
由映像的繪製方法,我們知道使用Canvas.drawBitmap(mBitmap, x, y, null)方法可以將映像繪製到螢幕的(x,y)座標位置上。
所以,要實現映像的平移,只需要改變映像繪製到螢幕上的(x,y)座標位置即可。
3.映像的旋轉
在Android中,可以使用Matrix來進行映像旋轉,Matrix是一個3*3的矩陣,專門用於映像變換匹配。Matrix沒有結構體,必須被初始化,可以通過reset()或set()方法來實現,如下:
mMatrix.reset();
初始化之後就可以通過setRotate()方法來設定想要的旋轉角度,如下:
mMatrix.setRotate();
旋轉角度設定完畢後,可以使用creatBitmap()方法建立一個經過旋轉處理的Bitmap對象,方法如下:
mBitmapRotate = Bitmap.creatBitmap(mBitmap, 0, 0, mBitmapWidth, mBitmapHight, mMatrix, true);
最後,將該Bitmap對象繪製到螢幕上,便實現了映像旋轉的操作。
4.映像的縮放
在Android中,同樣可以使用Matrix來實現映像的縮放。使用Matrix的postScale()方法來設定映像縮放的倍數,如下:
mMatrix.postScale();
縮放倍數設定完畢後,同樣需要使用creatBitmap()方法建立一個經過縮放處理的Bitmap對象。最後,將該Bitmap對象繪製到螢幕上,便實現了映像縮放的操作。
5.使用線程更新介面
要達到在介面中即時的看到映像的旋轉、縮放等效果,可以使用線程處理。線上程處理中加入postInvalidate()方法來實現。如下:
線程處理
1 public void run() {
2 while (!Thread.currentThread().isInterrupted()) {
3 try {
4 Thread.sleep(100);
5 }
6 catch (InterruptedException e) {
7 Thread.currentThread().interrupt();
8 }
9 postInvalidate(); //使用postInvalidate可以直接線上程中更新介面
10 }
11 }
6.執行個體
本執行個體中,定義了4個變數mBitmapToLeft、mBitmapToTop、mAngle以及mScale。變數mBitmapToLeft表示映像到螢幕左邊界的距離,mBitmapToTop表示映像到螢幕頂端的距離,mAngle表示映像旋轉的角度,mScale表示映像縮放的倍數。
通過上下左右四個按鍵可以實現圖片的上下左右平行移動,通過menu及back按鍵可以控製圖像的旋轉角度,通過音量加減按鍵可以控製圖像縮放的倍數。
線上程中處理這些操作,並調用postInvalidate()方法已到達即時重新整理介面的目的。
執行個體源碼如下:
MyView.java源碼
1 package com.example.android_imagedraw;
2
3 import android.content.Context;
4 import android.graphics.Bitmap;
5 import android.graphics.Canvas;
6 import android.graphics.Color;
7 import android.graphics.Matrix;
8 import android.graphics.drawable.BitmapDrawable;
9 import android.view.KeyEvent;
10 import android.view.View;
11
12 public class MyView extends View implements Runnable {
13
14 Bitmap mBitmap = null; //映像對象
15 Matrix mMatrix = new Matrix(); //Matrix對象
16
17 int mBitmapToLeft = 0; //映像距離螢幕左邊界的距離
18 int mBitmapToTop = 0; //映像距離螢幕頂端的距離
19
20 float mAngle = 0.0f; //旋轉角度
21 float mScale = 1.0f; //縮放倍數
22
23 public MyView(Context context) {
24 super(context);
25
26 mBitmap = ((BitmapDrawable) getResources().getDrawable
27 (R.drawable.fuwa)).getBitmap(); // 從資源檔中裝載圖片
28
29 new Thread(this).start(); //開啟線程
30 }
31
32 public void onDraw(Canvas canvas) {
33 super.onDraw(canvas);
34
35 canvas.drawColor(Color.GRAY); //設定畫布底色為灰色
36
37 mMatrix.reset(); //重設Matrix
38 mMatrix.setRotate(mAngle); //設定旋轉的角度
39 mMatrix.postScale(mScale, mScale); //設定縮放的倍數
40
41 //構建經過處理的新的Bitmap
42 Bitmap mBitmapRotate = Bitmap.createBitmap(mBitmap, 0, 0,
43 mBitmap.getWidth(), mBitmap.getHeight(), mMatrix, true);
44
45 MyView.drawImage(canvas, mBitmapRotate, mBitmapToLeft, mBitmapToTop);
46 }
47
48 // 按鍵按下事件
49 public boolean onKeyDown(int keyCode, KeyEvent event) {
50 switch (keyCode) { //處理平移
51 case KeyEvent.KEYCODE_DPAD_UP: //上方向鍵:上移
52 if (mBitmapToTop > 0){
53 mBitmapToTop--;
54 }
55 break;
56 case KeyEvent.KEYCODE_DPAD_DOWN: //下方向鍵:下移
57 if ((mBitmapToTop + mBitmap.getHeight()) < 800) {
58 mBitmapToTop++;
59 }
60 break;
61 case KeyEvent.KEYCODE_DPAD_LEFT: //左方向鍵:左移
62 if (mBitmapToLeft > 0) {
63 mBitmapToLeft--;
64 }
65 break;
66 case KeyEvent.KEYCODE_DPAD_RIGHT: //右方向鍵:右移
67 if ((mBitmapToLeft + mBitmap.getWidth()) < 480) {
68 mBitmapToLeft++;
69 }
70 break;
71 }
72
73 switch (keyCode) { //處理旋轉事件
74 case KeyEvent.KEYCODE_MENU: //MENU鍵:順時針旋轉
75 mAngle--;
76 break;
77 case KeyEvent.KEYCODE_BACK: //BACK鍵:逆時針旋轉
78 mAngle++;
79 break;
80 }
81
82 switch (keyCode) { //處理縮放事件
83 case KeyEvent.KEYCODE_VOLUME_DOWN: //音量減鍵:縮小
84 if (mScale > 0.3) {
85 mScale -= 0.1;
86 }
87 break;
88 case KeyEvent.KEYCODE_VOLUME_UP: //音量加鍵:放大
89 if (mScale < 1.5) {
90 mScale += 0.1;
91 }
92 break;
93 }
94 return true;
95 }
96
97 // 按鍵彈起事件
98 public boolean onKeyUp(int keyCode, KeyEvent event) {
99 return false;
100 }
101
102 // 線程處理
103 public void run() {
104 while (!Thread.currentThread().isInterrupted()) {
105 try {
106 Thread.sleep(100);
107 }
108 catch (InterruptedException e) {
109 Thread.currentThread().interrupt();
110 }
111 postInvalidate(); //使用postInvalidate可以直接線上程中更新介面
112 }
113 }
114
115 // 繪製Bitmap
116 public static void drawImage(Canvas canvas, Bitmap bitmap, int x, int y) {
117 canvas.drawBitmap(bitmap, x, y, null);
118 }
119 }
該執行個體原始映像效果1所示:
圖1 原始映像效果
經過平移旋轉及縮放後的效果2所示:
圖2 經過平移旋轉及縮放後的效果