生活随笔
收集整理的這篇文章主要介紹了
Android bitmap图片处理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、View轉換為Bitmap
? ?? ???在Android中所有的控件都是View的直接子類或者間接子類,通過它們可以組成豐富的UI界面。在窗口顯示的時候Android會把這些控件都加載到內存中,形成一個以ViewRoot為根節點的控件樹,然后由根節點開始逐級把控件繪制到屏幕上。
? ?? ???可以通過調用控件的setDrawingCacheEnabled(true)方法,開啟繪圖緩存功能,在繪制View的時候把圖像緩存起來,然后通過getDrawingCache()方法獲取這個緩存的Bitmap。需要注意的是,當不再使用這個Bitmap時,需要調用destroyDrawingCache()方法,釋放Bitmap資源。由于在繪制View到屏幕時緩存圖像會降低控件繪制的效率,因此只會在需要使用View的圖像緩存的時候才調用setDrawingCacheEnabled(true)方法開啟圖像緩存功能,當不再使用圖像緩存時需要調用setDrawingCacheEnabled(false)? 關閉圖像緩存功能。
? ?? ???這種方法在支持拖拽類型的應用中經常見到,在Android系統的Launcher應用中也使用了這種方法,當用戶拖拽應用的快捷圖標時,獲取到控件對應的Bitmap,然后操作這個Bitmap隨著手指移動。
? ?? ???下面通過一段代碼來說明如何獲取View對應的Bitmap。在代碼中使用了兩個ImageView并給它們都設置了顯示的圖片資源,然后把第一個ImageView對應的bitmap顯示到第二個ImageView中。由于在Activity的onCreate方法中調用這個方法,當執行Activity的onCreate方法時,控件還沒有準備好,所以需要使用Handler進行延遲操作,Java代碼如下:
?
[java]?view plaincopy
????public?void?getDrawingCache(final?ImageView?sourceImageView,?final?ImageView?destImageView)?{????????????????????????????new?Handler().postDelayed(new?Runnable()?{????????????????????????????????????????????????????@Override??????????????????????????public?void?run()?{??????????????????????????????????????????????????????????????????????????????????????????????????sourceImageView.setDrawingCacheEnabled(true);??????????????????????????????????????????????????????????????????Bitmap?mBitmap?=?sourceImageView.getDrawingCache();??????????????????????????????????????????????????????????????????destImageView.setImageBitmap(mBitmap);??????????????????????????????????????????????????????????????????????????????????????????????????????new?Handler().postDelayed(new?Runnable()?{????????????????????????????????????????????????????????????????????????????????????@Override??????????????????????????????????????????public?void?run()?{??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????destImageView.setImageResource(R.drawable.pet);??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????sourceImageView.setDrawingCacheEnabled(false);??????????????????????????????????????????????????????????????????????????????????????????????????sourceImageView.destroyDrawingCache();??????????????????????????????????????????}??????????????????????????????????},?DELAY_TIME);??????????????????????????}??????????????????},?DELAY_TIME);??????}?? [java]?view plaincopy
mImageView1.setImageResource(R.drawable.android);??????????mImageView2.setImageResource(R.drawable.pet);??????????getDrawingCache(mImageView1,?mImageView2);?? 運行效果如下:
Demo運行效果圖1
Demo運行效果圖2
二、圖片圓角處理
? ?? ???在Android中可以很容通過圖像疊加的規則為圖片添加圓角效果。正常情況下,在已有的圖像上繪圖時將會在其上面添加一層新的圖形。如果繪圖時使用的Paint是完全不透明的,那么它將完全遮擋住下面的圖像,如果Paint是部分透明的,那么它將會對重疊部分圖像的顏色疊加處理。通過PorterDuffXfermode規則可以設置繪制圖像時的疊加規則。PorterDuffXfermode是非常強大的轉換模式,使用它可以設置圖像疊加的Porter-Duff規則,來控制Paint如何與Canvas上已有的圖像進行疊加。下面列舉了常用的12條Porter-Duff規則及其表示的含義:
? ?? ???PorterDuff.Mode.CLEAR 清除畫布上圖像
? ?? ???PorterDuff.Mode.SRC 顯示上層圖像
? ?? ???PorterDuff.Mode.DST 顯示下層圖像
? ?? ???PorterDuff.Mode.SRC_OVER上下層圖像都顯示,下層居上顯示
? ?? ???PorterDuff.Mode.DST_OVER 上下層都顯示,下層居上顯示
? ?? ???PorterDuff.Mode.SRC_IN 取兩層圖像交集部分,只顯示上層圖像
? ?? ???PorterDuff.Mode.DST_IN 取兩層圖像交集部分,只顯示下層圖像
? ?? ???PorterDuff.Mode.SRC_OUT 取上層圖像非交集部分
? ?? ???PorterDuff.Mode.DST_OUT 取下層圖像非交集部分
? ?? ???PorterDuff.Mode.SRC_ATOP 取下層圖像非交集部分與上層圖像交集部分
? ?? ???PorterDuff.Mode.DST_ATOP 取上層圖像非交集部分與下層圖像交集部分
? ?? ???PorterDuff.Mode.XOR 取兩層圖像的非交集部分
? ?? ???下面使用PorterDuff.Mode.SRC_IN規則來給圖片添加圓角效果,主要的思路是先繪制一個圓角矩形,然后在上面繪制圖像,取圖像與圓角矩形的交集部分,只保留圖像。Java代碼如下:
?
[java]?view plaincopy
public?Bitmap?getRoundedBitmap()?{??????????Bitmap?mBitmap?=?BitmapFactory.decodeResource(getResources(),?R.drawable.frame);??????????????????Bitmap?bgBitmap?=?Bitmap.createBitmap(mBitmap.getWidth(),?mBitmap.getHeight(),?Config.ARGB_8888);??????????????????Canvas?mCanvas?=?new?Canvas(bgBitmap);????????????????????Paint?mPaint?=?new?Paint();??????????Rect?mRect?=?new?Rect(0,?0,?mBitmap.getWidth(),?mBitmap.getHeight());??????????RectF?mRectF?=?new?RectF(mRect);??????????????????float?roundPx?=?15;??????????mPaint.setAntiAlias(true);??????????????????mCanvas.drawRoundRect(mRectF,?roundPx,?roundPx,?mPaint);????????????????????????????mPaint.setXfermode(new?PorterDuffXfermode(PorterDuff.Mode.SRC_IN));??????????????????mCanvas.drawBitmap(mBitmap,?mRect,?mRect,?mPaint);????????????????????return?bgBitmap;??}?? 效果如下圖所示:
?
?
圖片圓角處理
三、圖片灰化處理
? ?? ???在Android中可以通過ColorMatrix類實現圖像處理軟件中的濾鏡效果,通過ColorMatrix類可以對位圖中的每個像素進行變換處理,達到特殊的濾鏡效果,下面通過一個例子來介紹如何通過ColorMatrix對圖像進行灰化處理,Java代碼如下: ?
[java]?view plaincopy
????public?Bitmap?getGrayBitmap()?{??????????????Bitmap?mBitmap?=?BitmapFactory.decodeResource(getResources(),?R.drawable.android);??????????????Bitmap?mGrayBitmap?=?Bitmap.createBitmap(mBitmap.getWidth(),?mBitmap.getHeight(),?Config.ARGB_8888);??????????????Canvas?mCanvas?=?new?Canvas(mGrayBitmap);??????????????Paint?mPaint?=?new?Paint();????????????????????????????????????????ColorMatrix?mColorMatrix?=?new?ColorMatrix();??????????????????????????mColorMatrix.setSaturation(0);??????????????????????????ColorMatrixColorFilter?mColorFilter?=?new?ColorMatrixColorFilter(mColorMatrix);??????????????????????????mPaint.setColorFilter(mColorFilter);??????????????????????????mCanvas.drawBitmap(mBitmap,?0,?0,?mPaint);????????????????????????????return?mGrayBitmap;???????????????}?? ?效果如下圖所示: ?
圖片灰化處理
四、提取圖像Alpha位圖
? ?? ???Android中的ARGB_8888類型的位圖由Alpha(透明度)、Red(紅)、Green(綠)、Blue(藍)四部分組成,其中Alpha部分也就是常說的Alpha通道,它控制圖像的透明度。在Android中Bitmap類提供了extractAlpha()方法,可以把位圖中的Alpha部分提取出來作為一個新的位圖,然后與填充顏色后的Paint結合重新繪制一個新圖像。下面通過一個例子來說明Bitmap類的extractAlpha()方法的使用,Java代碼如下: ?
[java]?view plaincopy
public?Bitmap?getAlphaBitmap()?{??????????BitmapDrawable?mBitmapDrawable?=?(BitmapDrawable)?getResources().getDrawable(R.drawable.enemy_infantry_ninja);??????????Bitmap?mBitmap?=?mBitmapDrawable.getBitmap();????????????????????????????????????????????Bitmap?mAlphaBitmap?=?Bitmap.createBitmap(mBitmap.getWidth(),?mBitmap.getHeight(),?Config.ARGB_8888);????????????????????Canvas?mCanvas?=?new?Canvas(mAlphaBitmap);??????????Paint?mPaint?=?new?Paint();????????????????????mPaint.setColor(Color.BLUE);??????????????????Bitmap?alphaBitmap?=?mBitmap.extractAlpha();??????????????????mCanvas.drawBitmap(alphaBitmap,?0,?0,?mPaint);????????????????????return?mAlphaBitmap;??}?? ?
提取圖像Alpha位圖
? ?? ???其中最后一幅圖片是把原圖片四個邊距縮小兩個dp,然后與Alpha位圖一起繪制的結果,讀者可以參考本章Demo中的getStrokeBitmap()方法。
五、圖像變換
? ?? ???Android開發框架提供了一個坐標變換矩陣Matrix類,它可以與Bitmap類的createBitmap方法結合使用,對圖像進行縮放、旋轉、扭曲等變換處理。圖像變換操作就是對坐標變換矩陣進行矩陣乘法運算,Matrix類中提供了一些簡便的方法如preScale、postScale、preRotate、postRotate、preSkrew、postSkrew、preTranslate、postTranslate等封裝了矩陣的運算,它們與Bitmap類的createBitmap方法結合使用可以很容易地對圖像進行縮放、旋轉、扭曲、平移操作。
1)圖像縮放?
? ?? ???使用Matrix類preScale或者postScale可以對圖像進行縮放操作,它的兩個參數分別為x和y坐標縮放比例,下面使用preScale對圖像進行放大0.75倍,Java代碼如下: ?
//getScaleBitmappublic Bitmap getScaleBitmap() {BitmapDrawable mBitmapDrawable = (BitmapDrawable) getResources().getDrawable(R.drawable.pet);Bitmap mBitmap = mBitmapDrawable.getBitmap();int width = mBitmap.getWidth();int height = mBitmap.getHeight();Matrix matrix = new Matrix();matrix.preScale(0.75f, 0.75f);Bitmap mScaleBitmap = Bitmap.createBitmap(mBitmap, 0, 0, width, height, matrix, true);return mScaleBitmap;}
?
效果如下圖所示:
?
圖像縮放
2)圖片旋轉
? ?? ???使用Matrix類preRotate或者postRotate可以對圖像進行旋轉操作,它只有一個參數表示旋轉的角度,下面使用preRotate對圖像順時針旋轉30度,Java代碼如下: ?
[java]?view plaincopy
????public?Bitmap?getRotatedBitmap()?{??????????????BitmapDrawable?mBitmapDrawable?=?(BitmapDrawable)?getResources().getDrawable(R.drawable.pet);??????????????Bitmap?mBitmap?=?mBitmapDrawable.getBitmap();??????????????int?width?=?mBitmap.getWidth();??????????????int?height?=?mBitmap.getHeight();????????????????????????????Matrix?matrix?=?new?Matrix();??????????????matrix.preRotate(45);??????????????Bitmap?mRotateBitmap?=?Bitmap.createBitmap(mBitmap,?0,?0,?width,?height,?matrix,?true);????????????????????????????return?mRotateBitmap;??????}?? 效果如下圖所示:
?
?
圖片旋轉
3)圖像傾斜
? ?? ???使用Matrix類preSkew或者postSkew可以對圖像進行傾斜操作,它的兩個參數分別為x和y坐標傾斜度,下面使用preSkew對圖像進行傾斜變換,Java代碼如下: ?
[java]?view plaincopy
public?Bitmap?getScrewBitmap()?{??????????BitmapDrawable?mBitmapDrawable?=?(BitmapDrawable)?getResources().getDrawable(R.drawable.pet);??????????Bitmap?mBitmap?=?mBitmapDrawable.getBitmap();??????????int?width?=?mBitmap.getWidth();??????????int?height?=?mBitmap.getHeight();????????????????????Matrix?matrix?=?new?Matrix();??????????matrix.preSkew(1.0f,?0.15f);??????????Bitmap?mScrewBitmap?=?Bitmap.createBitmap(mBitmap,?0,?0,?width,?height,?matrix,?true);????????????????????return?mScrewBitmap;??}?? ?效果如下圖所示:
?
?
圖像傾斜
4)圖像倒影
? ?? ???為圖像添加倒影效果之后,圖像看起來會有立體感,更有真實感,在Android中使用Matrix類可以很容易實現圖像的倒影效果。主要是Matrix的preScale方法的使用,給它設置負數縮放比例,圖像就會進行反轉。然后通過設置Shader添加漸變效果。Java代碼如下: ?
[java]?view plaincopy
????????private?Bitmap?getReflectedBitmap()?{??????????????????BitmapDrawable?mBitmapDrawable?=?(BitmapDrawable)?getResources().getDrawable(R.drawable.pet);??????????????????Bitmap?mBitmap?=?mBitmapDrawable.getBitmap();??????????????????int?width?=?mBitmap.getWidth();??????????????????int?height?=?mBitmap.getHeight();????????????????????????????????????Matrix?matrix?=?new?Matrix();??????????????????????????????????matrix.preScale(1,?-1);??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????Bitmap?mInverseBitmap?=?Bitmap.createBitmap(mBitmap,?0,?0,?width,?height,?matrix,?false);??????????????????Bitmap?mReflectedBitmap?=?Bitmap.createBitmap(width,?height*2,?Config.ARGB_8888);????????????????????????????????????????????????????Canvas?mCanvas?=?new?Canvas(mReflectedBitmap);??????????????????????????????????mCanvas.drawBitmap(mBitmap,?0,?0,?null);??????????????????mCanvas.drawBitmap(mInverseBitmap,?0,?height,?null);????????????????????????????????????????????????????Paint?mPaint?=?new?Paint();??????????????????Shader?mShader?=?new?LinearGradient(0,?height,?0,?mReflectedBitmap.getHeight(),?0x70ffffff,?0x00ffffff,?TileMode.MIRROR);??????????????????mPaint.setShader(mShader);??????????????????????????????????mPaint.setXfermode(new?PorterDuffXfermode(PorterDuff.Mode.DST_IN));??????????????????????????????????mCanvas.drawRect(0,?height,?width,?mReflectedBitmap.getHeight(),?mPaint);????????????????????????????????????return?mReflectedBitmap;??????????}?? 效果如下圖所示: ?
圖像倒影
5)圖像剪切
? ?? ???如果只需要圖像的一部分,就必須對圖像進行剪切處理,在原圖像上選擇一個剪切區域,使用PorterDuffXfermode圖像疊加規則,就可以把指定的圖像區域剪切下來,下面通過三個步驟來說明如果對圖像進行剪切操作。?
? ?? ???第一步,創建一個新位圖作為畫板,然后把原圖像畫到新位圖上面,Java代碼如下: [java]?view plaincopy
BitmapDrawable?bd?=?(BitmapDrawable)?getResources().getDrawable(??????????????????R.drawable.beauty);??Bitmap?bitmap?=?bd.getBitmap();??int?w?=?bitmap.getWidth();??int?h?=?bitmap.getHeight();??Bitmap?bm?=?Bitmap.createBitmap(w,?h,?Config.ARGB_8888);??Canvas?canvas?=?new?Canvas(bm);??Paint?mPaint?=?new?Paint();??mPaint.setAntiAlias(true);??mPaint.setStyle(Style.STROKE);??canvas.drawBitmap(bitmap,?0,?0,?mPaint);?? 效果如下圖所示:
?
第一步效果圖
? ?? ???第二步,繪制一個剪切區域,比如要剪切人物的臉部區域,需要在指定的位置繪制一個圓角矩形區域,代碼中的坐標是在調試中獲得,在其他分辨率下會有所不同,Java代碼如下: [java]?view plaincopy
int?deltX?=?76;??int?deltY?=?98;??DashPathEffect?dashStyle?=?new?DashPathEffect(new?float[]?{?10,?5,????????5,?5?},?2);RectF?faceRect?=?new?RectF(0,?0,?88,?106);??float?[]?faceCornerii?=?new?float[]?{30,30,30,30,75,75,75,75};??Paint?mPaint?=?new?Paint();mPaint.setColor(0xFF6F8DD5);??mPaint.setStrokeWidth(6);??mPaint.setPathEffect(dashStyle);??Path?clip?=?new?Path();clip.reset();??clip.addRoundRect(faceRect,?faceCornerii,?Direction.CW);canvas.save();canvas.translate(deltX,?deltY);??canvas.clipPath(clip,?Region.Op.DIFFERENCE);??canvas.drawColor(0xDF222222);??canvas.drawPath(clip,?mPaint);canvas.restore();?? 效果如下圖所示:
?
第二步效果
? ?? ???第三步,從原圖像上獲取指定區域的圖像,并繪制到屏幕上,java代碼如下: [java]?view plaincopy
Rect?srcRect?=?new?Rect(0,?0,?88,?106);??srcRect.offset(deltX,?deltY);??PaintFlagsDrawFilter?dfd?=?new?PaintFlagsDrawFilter(Paint.ANTI_ALIAS_FLAG,??Paint.FILTER_BITMAP_FLAG);??canvas.setDrawFilter(dfd);??canvas.clipPath(clip);canvas.drawBitmap(bitmap,?srcRect,?faceRect,?mPaint);?? 效果如下圖所示:
?
第三部效果圖
6)圖像合成
? ?? ???如果要為圖片添加水印,或者把幾張小圖片拼接成大圖片時,就需要利用圖像合成的方法,在前面實例代碼中已經使用了這種方法,就是創建新位圖作為畫板,然后在對應的位置上繪制其他圖像
轉載于:https://www.cnblogs.com/Free-Thinker/p/5571842.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的Android bitmap图片处理的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。