Android學習筆記11:圖像的平移、旋轉及縮放


  Android中,項目目錄下的res\drawable用來放置該項目的圖片資源。

  Android中提供了Bitmap類來獲取圖像文件信息,進行圖像的平移、旋轉及縮放等操作,並可以指定格式保存圖像文件。

1.圖像繪制

  在繪制圖像之前,需要從項目目錄下的res\drawable中獲取所需的圖片資源。我們可以通過資源索引來獲得該圖像對象Bitmap。具體方法如下(在項目目錄下的res\drawable中放置了一張名為fuwa.png的圖片):

  mBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.fuwa)).getBitmap():

  其中,getResources()方法的作用是取得資源對象;getDrawable()方法的作用取得資源中的Drawable對象,參數為資源索引idgetBitmap()方法的作用是得到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來實現圖像的縮放。使用MatrixpostScale()方法來設置圖像縮放的倍數,如下:

  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個變量mBitmapToLeftmBitmapToTopmAngle以及mScale。變量mBitmapToLeft表示圖像到屏幕左邊界的距離,mBitmapToTop表示圖像到屏幕頂端的距離,mAngle表示圖像旋轉的角度,mScale表示圖像縮放的倍數。

  通過上下左右四個按鍵可以實現圖片的上下左右平行移動,通過menuback按鍵可以控制圖像的旋轉角度,通過音量加減按鍵可以控制圖像縮放的倍數。

  在線程中處理這些操作,並調用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 經過平移旋轉及縮放后的效果

 

 

 

相關資料:

Android圖像處理之Bitmap類:http://www.open-open.com/lib/view/open1333418945202.html

 Android圖片處理(MatrixColorMatrix):http://www.cnblogs.com/leon19870907/articles/1978065.html

 


免責聲明!

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



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