1. 程式人生 > >Android中Bitmap的剪下與拉伸

Android中Bitmap的剪下與拉伸

最近做的專案中經常會遇到影象的剪下與拉伸,當中也遇到了不少麻煩,現在在此總結下。

1.     Bitmap的剪下

通常是用到了Bitmap類的createBitmap方法的幾個過載方法:

public static Bitmap createBitmap (Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)

該方法結合Matrix(矩陣)來實現Bitmap的剪下,很多人對這個方法的剪下過程比較模糊,經過我的測試,該方法剪下圖片其實是分為兩個步驟的。第一步先對源影象從(x,y)位置擷取寬為width,高為height的影象快取起來。第二步對這個快取影象進行matrix變換生成新的Bitmap作為返回值。這裡一定要注意,由於第一步的剪下原理,x,y,width,height必須滿足   x+width<=source.getWidth(), h+height<=source.getHeight();否則會丟擲異常。

public static Bitmap createBitmap (Bitmap source, int x, int y, int width, int height)該方法和上面的方法類似 ,只不過去掉了Matrix變換。本人覺的 若只是單純的剪下影象還是用這個比較靠譜因為若是把影象剪下和影象的矩陣變換混在一起 往往會得不到想要的效果。

2.  Bitmap的拉伸

Bitmap的拉伸最有效的方法就是:

Bitmap mBitmap = Bitmap.createScaledBitmap(bmp, mScreenWidth, mScreenHeight, true);

該方法是以源影象的左上角為中心將源影象拉伸後生成一個寬為 mScreenWidth,高度為mScreenHeight的新影象作為返回值。遊戲開發中為了適應不同螢幕尺寸的手機,通常都會將遊戲背景按比例拉伸來適配相應的螢幕尺寸,這裡就是用到了該方法。需要注意的一點是該方法不是按比例拉伸的,為了拉伸後的影象不變型 ,通常需要事先計算好按比例拉伸好後的寬高。

圖片拉伸還有另一種方法:

ImageView  imgvLogo = findViewById(R.id.imgv_Logo);

imgvLogo.setScaleType(ImageView.ScaleType.CENTER);

即將影象作為ImageView的背景 ,然後通過設定ImageView的scaleType屬性來拉伸影象。這種用法的優點是不用建立新的物件節省記憶體,缺點是靈活性差。這裡順帶介紹下scaleType用到的幾個列舉值:

fitXY : 拉伸圖片(不按比例)以填充View的寬高

fitStart : 按比例拉伸圖片,拉伸後圖片的高度為View的高度,且顯示在View的左邊           fitCenter :按比例拉伸圖片,拉伸後圖片的高度為View的高度,且顯示在View的中間。

fitEnd :按比例拉伸圖片,拉伸後圖片的高度為View的高度,且顯示在View的右邊               center : 按原圖大小顯示圖片,但圖片寬高大於View的寬高時,截圖圖片中間部分            顯示

centerCrop: 按比例放大原圖直至等於某邊View的寬高顯示。

centerInside :當原圖寬高小於或等於View的寬高時,按原圖大小居中顯示;反之將           原圖縮放至View的寬高居中顯示。

3.      細心的同學其實已經注意到了,上述影象的剪下與拉伸都建立了一個新的Bitmap  物件,如果開發中需要對很多個圖片做拉伸或者剪下,使用上述方法就會對系統記憶體造成極大的浪費。那麼有什麼方法可以避免這種情況呢? 答案就是 在繪圖過程中對影象進行剪下或拉伸。

這裡的繪圖中剪下與拉伸影象本質上是繪製源影象的部分割槽域而已,用到的方法是:

public void drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint) ;

這個方法是Canvas類的方法, src 是原始影象的部分矩形區域, dst是對原始影象做了剪下或或其他操作(matrix變換)後的影象矩形區域。這裡並沒有生成新的物件,只是繪製了源影象的部分割槽域。

還有一種繪製圖像的方法用於影象的Matrix變化,同樣也不會生成新的物件:

public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint);

這個也是Canvas類的方法,源影象的變化操作都儲存在matrix裡,繪製圖像時會先對源影象進行相應的變化然後在繪製再畫布上。關於影象的Matrix變換比較複雜,我會在後續的文章中詳細介紹。

轉載自:http://labs.easymobi.cn/?p=3581