Bitmap 是圖形類,Android 系統支持的圖片格式有 png、jpg、bmp 等。
對位圖操作在游戲中是很重要的知識點,比如游戲中需要兩張除了大小之外其他完全相同的圖,那么如果會對位圖進行縮放操作,很容易就節約了一張圖片資源;這樣既節約了美工的時間,更節約游戲安裝包的大小;當然除了縮放,還有很多操作,例如對位圖進行旋轉、鏡像、設置透明度等等操作都會節約很大的資源。
首先創建一個位圖實例。位圖的實例不能通過 new,如果想通過一張圖片資源文件創建一個位圖,則要通過位圖工廠來索引圖片資源文件,從而生成一張位圖實例,如下所示:
BitmapFactory.decodeResource(Resources res,int Id)
作用:通過資源文件生成一張位圖
第一個參數:資源實例
第二個參數:資源ID
懂得如何通過圖片資源創建位圖實例后,下面就來詳細介紹如何操作位圖。創建項目“BitmapProject”,游戲框架為 SurfaceView 游戲框架。具體步驟參照“11.游戲開發基礎(SurfaceView 游戲框架、View 和 SurfaceView 的區別)”。
我這個准備了一張圖片pic01.png:

修改 MySurfaceView.java ,代碼中 bmp 是由圖片資源生成一個位圖實例。
Bitmap bmp = BitmapFactory.decodeResource(this.getResources(),R.drawable.pic01);
下面講解位圖常用的操作函數:
1.繪制位圖
/** * 在畫布上繪制一張位圖 * 第一個參數:位圖實例 * 第二、三個參數:位圖的X,Y坐標 * 第四個參數:畫筆實例 */ canvas.drawBitmap(bmp,0,0,paint);
代碼執行效果如下:

2.旋轉位圖
/** * 旋轉畫布 * 第一個參數:畫布旋轉的角度 * 第二、三個參數:畫布的旋轉點 * 如果旋轉的角度大於0,順時針旋轉;旋轉的角度小於0,則逆時針旋轉 * * Canvas 中旋轉畫布還有一個函數:rotate(float degress),參數傳入的是旋轉畫布的角度,此種方法無法設置旋轉點,默認旋轉點為屏幕中心點。 */ canvas.rotate(30,bmp.getWidth()/2,bmp.getHeight()/2); canvas.drawBitmap(bmp,0,0,paint);
代碼執行效果如下:

如果想讓位圖進行旋轉,那么通過這種旋轉畫布的方法即可實現。但是當使用此種實現畫布旋轉時,需要注意兩點:
• 如果希望圖片的旋轉是以圖片中心點進行旋轉,那么在使用 rotate 旋轉畫布函數對畫布進行旋轉時,其旋轉點坐標應該設置為圖片的中心點坐標;
• rotate 函數是對整個畫布進行旋轉操作,也就是意味着,畫布上所有繪制的元素都會因畫布的旋轉而進行對應的旋轉。
例如代碼修改為:
canvas.rotate(30,bmp.getWidth()/2,bmp.getHeight()/2); canvas.drawBitmap(bmp,0,0,paint); canvas.drawBitmap(bmp,100,0,paint);
當旋轉畫布后,繪制兩個位圖,效果圖如下所示:

通過圖片可以明顯看出,第二次繪制的圖片也被旋轉!當然這並不是想要的效果,那么如果只想對一張位圖進行旋轉操作該如何實現呢?
Canvas 類中有兩個很重要的函數 save() 與 restore():
• save():作用是用於保存當前畫布的狀態;
• restore():作用是恢復上次保存的畫布狀態。
這兩個函數是配對出現的。 注意 save() 函數出現的次數不能大於 restore() 函數。
對位圖旋轉代碼進行修改:
//先保持畫布的狀態 canvas.save(); canvas.rotate(30,bmp.getWidth()/2,bmp.getHeight()/2); canvas.drawBitmap(bmp,0,0,paint); //再將畫布恢復狀態 canvas.restore(); canvas.drawBitmap(bmp,100,0,paint);
項目運行效果如下:

所以,當對畫布進行縮放、旋轉和位移操作時,為了保證其他繪制的元素不受影響,應該利用 save() 與 restore() 對畫布進行適當的保持與恢復操作。
除此之外 還有一種對位圖進行旋轉的方式,就是利用矩陣 Matrix 來實現,代碼如下:
//首先創建一個矩陣實例 Matrix mx = new Matrix(); //然后對矩陣進行旋轉縮放 mx.postRotate(30,bmp.getWidth()/2,bmp.getHeight()/2); //最后使用畫布繪制位圖時,將矩陣信息作為參數傳入 canvas.drawBitmap(bmp,mx,paint);
效果如下:

Matrix 類的 postRotate 函數與 Canvas 中的 rotate 函數的作用相同,參數表示的函數也都一致。
使用矩陣對位圖進行操作時,可以免去對畫布的狀態保持和恢復,因為矩陣就是針對單獨位圖進行的操作,所以不會影響畫布其他元素的繪制。
3.平移位圖
//創建位圖實例 Bitmap bmp = BitmapFactory.decodeResource(this.getResources(), R.drawable.pic01); canvas.save(); /** * 平移圖片 * 第一個參數:在X軸上平移畫布的距離 * 第二個參數:在Y軸上平移畫布的距離 */ canvas.translate(100, 0); canvas.drawBitmap(bmp, 0, 0, paint); canvas.restore(); canvas.save(); canvas.translate(-90, 280); canvas.drawBitmap(bmp, 0, 0, paint); canvas.restore(); canvas.save(); //利用矩陣也可以完成對位圖的平移操作 Matrix maT = new Matrix(); maT.postTranslate(380,-90); canvas.drawBitmap(bmp, maT, paint); canvas.restore();
代碼執行效果如下:

4.縮放位圖
//創建位圖實例 Bitmap bmp = BitmapFactory.decodeResource(this.getResources(), R.drawable.pic01); canvas.save(); canvas.drawText("原圖:", 0, 20, paint); canvas.drawBitmap(bmp, 0, 40, paint); canvas.restore(); canvas.save(); /** * 對畫布進行縮放 * 第一個參數:對畫布X軸的縮放比例 * 第二個參數:對畫布Y軸的縮放比例 * 此方法無法設置縮放起始點,默認縮放起始點為屏幕的(0,0)點 */ //縮小到0.5倍 canvas.scale(0.5f, 0.5f); canvas.drawBitmap(bmp, 600, 40, paint); canvas.restore(); canvas.save(); /** * 對畫布進行縮放 * 第一個參數:對畫布X軸的縮放比例 * 第二個參數:對畫布Y軸的縮放比例 * 第三、四個參數:對畫布進行縮放的起始點 */ //放大為2倍 canvas.scale(2f, 2f, 0, 0); canvas.drawBitmap(bmp, 0, 220, paint); canvas.restore(); canvas.save(); //,利用矩陣實現對位圖的縮放操作,當前為縮小到0.75倍 Matrix ma = new Matrix(); ma.postTranslate(700, 40); ma.postScale(0.75f, 0.75f); canvas.drawBitmap(bmp,ma, paint); canvas.restore();
代碼執行效果如下:

5.鏡像反轉位圖
//創建位圖實例 Bitmap bmp = BitmapFactory.decodeResource(this.getResources(), R.drawable.pic01); canvas.save(); canvas.drawText("原圖:", 10, 20, paint); canvas.drawBitmap(bmp, 10, 40, paint); canvas.restore(); //X 軸鏡像 canvas.save(); canvas.drawText("X 軸鏡像:", 10, 320, paint); //當X軸的比例值小於0時,其實是對畫布進行X軸的鏡像后的縮放。 canvas.scale(-1, 1, 10+bmp.getWidth()/2, 340+bmp.getHeight()/2); canvas.drawBitmap(bmp, 10, 340,paint); canvas.restore(); //Y 軸鏡像 canvas.save(); canvas.drawText("Y 軸鏡像:", 10, 620, paint); //利用矩陣實現對位圖的鏡像操作 Matrix ma = new Matrix(); ma.postTranslate(10, 640); ma.postScale(1, -1, bmp.getWidth()/2+10,bmp.getHeight()/2+640); canvas.drawBitmap(bmp,ma, paint); canvas.restore(); //XY 軸鏡像 canvas.save(); canvas.drawText("XY軸鏡像:", 10, 920, paint); canvas.scale(-1, -1, 10+bmp.getWidth()/2, 940+bmp.getHeight()/2); canvas.drawBitmap(bmp, 10, 940,paint); canvas.restore();
代碼執行效果如下:

在游戲開發中,一般最經常用的是 png 格式的圖片,原因在於 png 格式的圖片支持透明度,當然這不是必須的。
