Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 開發入門 >> Android 動態旋轉圖片

Android 動態旋轉圖片

編輯:開發入門

Bitmap與Matrix旋轉ImageVIEw

先前曾看過ImageView Widget的展示,雖可以將許多ImageView層層疊疊放在一起,再控制ImageView的圖片來模擬動畫的效果,但ImageView默認是沒辦法旋轉的,那麼要如何讓ImageVIEw產生旋轉的效果呢?

要旋轉ImageView其實很簡單,先將前一次ImageView裡的圖片放入暫存Bitmap,接著再利用Bitmap.createBitmap來創建新的Bitmap對象,在創建新的Bitmap對象的同時,搭配Matrix對象裡的setRotate()方法動態旋轉新創建的Bitmap。然後,再將旋轉好的Bitmap對象,以新構造的方式創建新的Bitmap對象,最後再"放入"ImageView中顯示,就可以達到旋轉ImageView的效果,這個范例的學習重點則在於如何操作BitmapFactory.decodeResource()方法來使用Matrix對圖像的控制,為了讓旋轉能夠通過事件來進行,所以在Layout中配置了兩個Button Widget,以及一個ImageVIEw Widget。當單擊"向左旋轉"按鈕時,畫面的小河馬就會向左傾斜;當單擊"向右旋轉"按鈕時,畫面的小河馬就會向右傾斜。

程序設置了兩個按鈕,分別處理向左及向右旋轉的語句,而為了防止旋轉角度超過數值范圍,所以默認參考值(ScaleAngle)向左最多為?5、向右則最多為5,再利用Matrix對象裡的matrix.setRotate()方法,將5*ScaleAngle的計算結果傳入作為參數,使其產生每次至少5°的變化,在?20°和20°之間。
Bitmap.createBitmap()方法所扮演的角色為產生暫存的Bitmap,使之每一次(單擊按鈕時)都"復制"來自原始圖"mySourceBmp"的數據,自坐標(0,0)-(原圖寬,原圖高)復制成為新圖,而由於createBitmap()方法的第六個參數可指定Matrix對象,這也就是本范例程序旋轉畫面的唯一關鍵。

Java代碼:
  1. public class EX04_24 extends Activity {
  2. private Button mButton1;
  3. private Button mButton2;
  4. private TextView mTextVIEw1;
  5. private ImageView mImageVIEw1;
  6. private int ScaleTimes;
  7. private int ScaleAngle;
  8. /** Called when the activity is first created. */
  9. @Override
  10. public void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentVIEw(R.layout.main);
  13. mButton1 =(Button) findVIEwById(R.id.myButton1);
  14. mButton2 =(Button) findVIEwById(R.id.myButton2);
  15. mTextView1 = (TextView) findViewById(R.id.myTextVIEw1);
  16. mImageView1 = (ImageView) findViewById(R.id.myImageVIEw1);
  17. ScaleTimes = 1;
  18. ScaleAngle = 1;
  19. final Bitmap mySourceBmp = BitmapFactory.decodeResource(getResources(), R.drawable.hippo); final int widthOrig = mySourceBmp.getWidth();
  20. final int heightOrig = mySourceBmp.getHeight();
  21. /* 程序剛運行,加載默認的Drawable */
  22. mImageVIEw1.setImageBitmap(mySourceBmp);
  23. /* 向左旋轉按鈕 */
  24. mButton1.setOnClickListener(new Button.OnClickListener() {
  25. @Override
  26. public void onClick(VIEw v) {
  27. // TODO Auto-generated method stub
  28. ScaleAngle--;
  29. if(ScaleAngle<-5) {
  30. ScaleAngle = -5;
  31. }
  32. /* ScaleTimes=1,維持1:1的寬高比例*/
  33. int newWidth = widthOrig * ScaleTimes;
  34. int newHeight = heightOrig * ScaleTimes;
  35. float scaleWidth = ((float) newWidth)
  36. / widthOrig; float scaleHeight = ((float) newHeight) /
  37. heightOrig; Matrix matrix = new Matrix();
  38. /* 使用Matrix.postScale設置維度 */
  39. matrix.postScale(scaleWidth, scaleHeight);
  40. /* 使用Matrix.postRotate方法旋轉Bitmap*/
  41. //matrix.postRotate(5*ScaleAngle);
  42. matrix.setRotate(5*ScaleAngle);
  43. /* 創建新的Bitmap對象 */
  44. Bitmap resizedBitmap = Bitmap.createBitmap (mySourceBmp, 0, 0, widthOrig, heightOrig, matrix, true);
  45. /**/
  46. BitmapDrawable myNewBitmapDrawable = new BitmapDrawable(resizedBitmap); mImageVIEw1.setImageDrawable(myNewBitmapDrawable);
  47. mTextVIEw1.setText(Integer.toString(5*ScaleAngle));
  48. }
  49. });
  50. /* 向右旋轉按鈕 */
  51. mButton2.setOnClickListener(new Button.OnClickListener() {
  52. @Override
  53. public void onClick(VIEw v) {
  54. // TODO Auto-generated method stub
  55. ScaleAngle++;
  56. if(ScaleAngle>5) {
  57. ScaleAngle = 5;
  58. }
  59. /* ScaleTimes=1,維持1:1的寬高比例*/
  60. int newWidth = widthOrig * ScaleTimes;
  61. int newHeight = heightOrig * ScaleTimes;
  62. /* 計算旋轉的Matrix比例 */
  63. float scaleWidth = ((float) newWidth)
  64. / widthOrig; float scaleHeight = ((float) newHeight)
  65. / heightOrig; Matrix matrix = new Matrix();
  66. /* 使用Matrix.postScale設置維度 */
  67. matrix.postScale(scaleWidth, scaleHeight);
  68. /* 使用Matrix.postRotate方法旋轉Bitmap*/
  69. //matrix.postRotate(5*ScaleAngle);
  70. matrix.setRotate(5*ScaleAngle);
  71. /* 創建新的Bitmap對象 */
  72. Bitmap resizedBitmap = Bitmap.createBitmap (mySourceBmp, 0, 0, widthOrig, heightOrig, matrix, true);
  73. /**/
  74. BitmapDrawable myNewBitmapDrawable = new BitmapDrawable(resizedBitmap); mImageView1.setImageDrawable(myNewBitmapDrawable); mTextVIEw1.setText(Integer.toString(5*ScaleAngle));
  75. }
  76. });

  77. }

  78. }

Matrix類的設計,不僅是二維空間的結構,事實上,它原始的設計是3 3的矩陣,由於Matrix類並不需要構造器,因此在聲明Matrix對象之後,可以調用reset()方法或set()方法產生新的矩陣,如同本范例的setRotate一樣。
回來看看,我們在這個范例程序中,也放上了添加注釋的語句matrix.postRotate(5*ScaleAngle),經測試後,無論是使用postRotate()方法或setRotate()方法,效果都是相同的,但較困惑的是Google的官方SDK文件中,所描述的postRotate()方法的原型如下:

Java代碼:
  1. boolean postRotate(float degrees, float px, float py)

經測試postRotate()方法並沒有第二、第三個參數需要傳遞,這是在android SDK 1.0_r2才發現的,未來可能會因為改版而有所改變。
另外,Matrix還有一個常用的postScale()方法,可通過矩陣的方式用以指定其縮放大小,其原型如下:

Java代碼:
  1. public boolean postScale(float sx, float sy, float px, float py)

使用的公式為:M' = S(sx, sy, px, py)* M,示意的片段程序如下。

Java代碼:
  1. final Bitmap mySourceBmp = BitmapFactory.decodeResource(getResources(), R.drawable.hippo); Matrix mx = new Matrix();
  2. mx.postScale ( (float)20/mySourceBmp.getWidth(), (float)20/mySourceBmp.getHeight() ); mySourceBmp = Bitmap.createBitmap (bm, 0, 0, bm.getWidth(), bm.getHeight(), mx, true); mImageVIEw1.setImageBitmap(mySourceBmp);
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved