Bitmap.createBitmap實現裁剪圖片適配屏幕


在編寫MusicPlayer的過程中,播放歌曲時搜索歌手的圖片,並動態地將圖片設為當前Activity的背景。當圖片大小與屏幕不適應時會導致圖片被拉神效果很不好看。比如你的手機分辨率是320X480,而圖片的分辨率是320X320,那么,該圖片將被拉長。

Bitmap.createBitmap - peculiar - art of devil

 

       那么,如何放大圖片的同時不影響其顯示效果呢?
       網上有用  drawable.setTileModeXY(TileMode.REPEAT , TileMode.REPEAT )的方法來設置圖片的平鋪,但是我沒有試驗成功,
Bitmap.createBitmap - peculiar - art of devil
 
 
於是嘗試了Bitmap.createBitmap方法。

       下面是Google官方文檔對createBitmap方法的解釋

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

Added in  API level 1

Returns an immutable bitmap from subset of the source bitmap, transformed by the optional matrix. The new bitmap may be the same object as source, or a copy may have been made. It is initialized with the same density as the original bitmap. If the source bitmap is immutable and the requested subset is the same as the source bitmap itself, then the source bitmap is returned and no new bitmap is created.

Parameters
source The bitmap we are subsetting
x The x coordinate of the first pixel in source
y The y coordinate of the first pixel in source
width The number of pixels in each row
height The number of rows
m Optional matrix to be applied to the pixels
filter true if the source should be filtered. Only applies if the matrix contains more than just translation.
Returns
  • A bitmap that represents the specified subset of source
Throws
IllegalArgumentException if the x, y, width, height values are outside of the dimensions of the source bitmap.

各參數含義:

       surce:用來剪裁的圖片源;
       x:剪裁x方向的起始位置;
       y: 剪裁y方向的起始位置;
       width:剪裁的寬度;
       height:剪裁的高度;
       filer:不是很清楚它的作用 - -!
需要注意的是:必須滿足條件:x+width<=bitmap.width()(圖片源的原始寬度)否則會拋出 IllegalArgumentException異常。
 
       我遇到的問題是圖片為320X320,手機屏幕是320X480,需將圖片按照手機屏幕的比例剪裁后再適當放大。這里的執行過程並非是先放大再剪裁。
下面是思路:
       一、獲取手機屏幕寬高(width,height)與圖片的寬高(widthDrawable,heightDrawable);
       二、計算其比例,取大的。比如 width/widthDrawable=1.0,height/heightDrawable=1.5,那么取scale=1.5;
       三、利用Matrix構建縮放矩陣:
                     Matrix matrix = new Matrix(); 
                     matrix.postScale(scale, scale);
       四、計算起始剪裁的位置x,y和剪裁寬度width,高度height;
       五、調用createBitmap方法,在原圖片的基礎上剪裁新的圖片並縮放相應的比例。
 
下面是相關的代碼:

@SuppressWarnings("deprecation")
private void setDrawable(Bitmap backGroundMap, RelativeLayout lrcBackGround) {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;//獲取屏幕的寬和高
Log.v("franco-width", "width = " + width);
Log.v("franco-height", "height = " + height);//320X480

int widthDrawable = backGroundMap.getWidth();
int heightDrawable = backGroundMap.getHeight();//獲取背景圖片的寬和高
Log.v("franco-widthDrawable", "widthDrawable = " + widthDrawable);
Log.v("franco-heightDrawable", "heightDrawable = " + heightDrawable);//320X320

float scaleWidth = (float)width/widthDrawable;
float scaleHeight = (float)height/heightDrawable;//寬高比
Log.v("franco", "scaleWidth = " + scaleWidth);
Log.v("franco", "scaleHeight = " + scaleHeight);//1.0:1.5

Bitmap resizeBmp;
Matrix matrix = new Matrix();
if(scaleWidth < scaleHeight) { float scale = scaleHeight;//取大的 matrix.postScale(scale, scale);//縮放比例 int xStart = (int)(widthDrawable-widthDrawable/scale)/2; Log.v("franco-xStart", "xStart = " + xStart); /* * Bitmap source:要從中截圖的原始位圖 * int x:起始x坐標 * int y:起始y坐標 * int width:要截的圖的寬度 * int height:要截的圖的寬度 * x+width must be <= bitmap.width()不然會報錯 * 原理是先截圖再縮放,而不是先縮放再截圖!! */ resizeBmp = Bitmap.createBitmap(backGroundMap, xStart, 0, (int)(widthDrawable/scale), heightDrawable, matrix, true); } else { float scale = scaleWidth; matrix.postScale(scale, scale); int yStart = (int)(scaleHeight-scaleHeight/scale)/2; Log.v("franco-yStart", "yStart = " + yStart); resizeBmp = Bitmap.createBitmap(backGroundMap, 0, yStart, widthDrawable, (int)(heightDrawable/scale), matrix, true); } //Bitmap 轉化為 Drawable BitmapDrawable drawable = new BitmapDrawable(getResources(), resizeBmp); //drawable.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT); lrcBackGround.setBackgroundDrawable(drawable); lrcBackGround.getBackground().setAlpha(150);//將背景該圖片透明度設低,避免歌詞顯示效果不好,數值越大透明度越高 }

最后效果如下:
Bitmap.createBitmap - peculiar - art of devil
 

 

但是這樣做必將會剪裁掉部分原圖,如果不剪裁的話圖片的比例會失真,期待更好地方案。


免責聲明!

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



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