Android繪圖總結(Bitmap,Canvas,Paint,圓角)
最近老是和繪圖打交道,經常用到Canvas,bitmap,Paint,但是對它們的理解總是模糊,這裡作下總結,加深對繪圖的理解。
要掌握Android的畫圖,首先就要了解一下,基本用到的圖形介面:
1.Bitmap,可以來自資源/檔案,也可以在程式中建立,實際上的功能相當於圖片的儲存空間,儲存著畫素
2.Canvas,緊密與Bitmap聯絡,把Bitmap比喻內容的話,那麼Canvas就是提供了眾多方法操作Bitamp的平臺,執行畫圖的命令(向bitmap執行寫操作)
3.Paint,與Canvas緊密聯絡,是"畫板"上的筆刷工具,也用於設定View控制元件上的樣式,使用的顏色和風格
4.Drawable,如果說前三者是看不見地在記憶體中畫圖,那麼Drawable就是把前三者繪圖結果表現出來的介面。Drawable多個子類,例如:點陣圖(BitmapDrawable)、圖形(ShapeDrawable)、圖層(LayerDrawable)等。
Bitmap簡介
1. 使用BitmapDrawable獲取點陣圖
讀取InputStream使用BitmapDrawable (InputStream is)構造一個BitmapDrawable,使用BitmapDrawable類的getBitmap()獲取得到點陣圖:
InputStream is=res.openRawResource(R.drawable.ic_launcher); BitmapDrawable bmpDraw=new BitmapDrawable(is); Bitmap bmp=bmpDraw.getBitmap();
上面是通過解碼點陣圖來獲取點陣圖,如果你在解析大圖片遇到OOM問題,不妨嘗試這個方法,這個方法利用JNI呼叫來解析bitmap,減輕了java層空間的壓力。
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
2.通過Bitmap的createBitmap方法建立
createBitmap(Bitmap source, int x, inty, int width, int height, Matrix m, boolean filter); createBitmap(int width, int height, Bitmap.Config config); createBitmap(Bitmap source, int x, int y, int width, int height);
matrix 指定對bitmap畫素的操作, width,height用來指定建立圖片的大小,config用來指定建立圖片的質量, 其中config有共有4個標準: ALPHA_8,ARGB_4444,ARGB_8888,RBG_565,這些標準分別定義圖片畫素儲存的情況,RBG_565是比較常用的, ARBG_8888指定的圖片質量最高
A:Alpha透明度
R:Red紅色
G:Green綠色
B:Blue藍色
ALPHA_8,ARGB_4444,ARGB_8888都是透明的點陣圖,也就是所字母A代表透明.
ARGB_8888:意味著有四個引數,即A,R,G,B,每一個引數由8bit來表示.也就是32位的點陣圖
同理:
RGB_565:意味著有三個引數,R,G,B,三個引數分別佔5bit,6bit,5bit.也就是16位的點陣圖
Canvas簡介
canvas就是一個畫布,需要藉助paint(畫筆)來實現畫圖,比如:
drawRoundRect (RectF rect, float rx, float ry, Paint paint)
畫橢圓的方法:rect表示要畫的區域,rx是x方向半徑,ry是y方向半徑,paint是畫筆
canvas藉助paint實現簡單圖形的繪畫,不多說了,比較簡單,下面介紹一下畫圓角:
/** * 獲取圓角圖片 * @param bitmap * @param roundPx * @return */ public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx){ Bitmap output = null; try { if(bitmap == null) return null; output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); } catch (OutOfMemoryError e) { System.gc(); output = null; } return output; }
上面的Rect和RectF,這兩個都是矩形,說一下主要區別:
1、精度不一樣,Rect是使用int型別作為數值,RectF是使用float型別作為數值
2、兩個型別提供的方法也不是完全一致(具體查api)
畫圓角關鍵的一步在這裡:
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
借一張圖來說明:
先繪製的就是Dst,再繪製的是Src,上面的16中效果,可以隨意組合展示不同的效果。
最後說一下canvas的save和restore方法:
❑ save:用來儲存Canvas的狀態。save之後,可以呼叫Canvas的平移、放縮、旋轉、錯切、裁剪等操作。
❑ restore:用來恢復Canvas之前儲存的狀態。防止save後對Canvas執行的操作對後續的繪製有影響。
Paint簡介
Android 中的Paint類主要方法:
setAntiAlias: 設定畫筆的鋸齒效果。
setColor: 設定畫筆顏色
setARGB: 設定畫筆的a,r,p,g值。
setAlpha: 設定Alpha值
setTextSize: 設定字型尺寸。
setStyle: 設定畫筆風格,空心或者實心。
setStrokeWidth: 設定空心的邊框寬度。
getColor: 得到畫筆的顏色
getAlpha: 得到畫筆的Alpha值。
最後總結一下畫圓角的三種方法:
1.直接程式碼控制
比如自定義ImageView,在OnDraw方法中對drawable進行處理,繪製到canvas上面即可,但是onDraw方法可能經常被呼叫,效率不高。
或者在imagevewi設定bitmap的時候進行處理,這個也是一種方法。
2.xml中設定shape
利用shape檔案來定義一些圓角效果,設定成背景,這種方法值得推薦。
3.利用遮罩層實現
對imageview蒙上一層圓角圖片(需要.9圖片),這個方法也很好,不影響繪畫效率。
儘量使用第二種方法,依次第三種,最後沒辦法那就第一種.看到一篇文章寫的有,就不重複造船了: