1. 程式人生 > >Android繪圖總結(Bitmap,Canvas,Paint,圓角)

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, int
y, 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));

借一張圖來說明:

20140426213750328

先繪製的就是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圖片),這個方法也很好,不影響繪畫效率。

儘量使用第二種方法,依次第三種,最後沒辦法那就第一種.看到一篇文章寫的有,就不重複造船了: