天天看點

從原理上去了解圓形頭像 Android ImageView圓形頭像 圖檔完全解析

文章來自于:http://my.oschina.net/u/2241960/blog/321024

我們在做項目的時候會用到圓形的圖檔,比如使用者頭像,類似QQ。使用者在用QQ更換頭像的時候,上傳的圖檔都是矩形的,但顯示的時候确是圓形的。

從原理上去了解圓形頭像 Android ImageView圓形頭像 圖檔完全解析

 原理:先在canvas上面畫一個圓形,參照圓形的起點坐标、半徑,再畫一個邊長為圓的直徑的bitmap(這個bitmap就是你想畫的圓形頭像),此時圓和bitmap重疊在一起,圓在下面,bitmap在上面,bitmap覆寫着圓(如下圖,其實圓是在bitmap後面的,看不到的。為了形象,我用ps搞了一個半透明圓效果)。

從原理上去了解圓形頭像 Android ImageView圓形頭像 圖檔完全解析

關鍵點來了:這時,圓形和bitmap相交的部分正是圓大小的面積,如果能将bitmap與圓相交之外的部分去掉,那麼我們看到的是不是bitmap的圓形部分?(如下圖藍色部分)

從原理上去了解圓形頭像 Android ImageView圓形頭像 圖檔完全解析

搞清楚原理後,下面我門來看代碼是怎麼實作的。

<span style="font-family:Microsoft YaHei;font-size:14px;">    public Bitmap toRoundBitmap(Bitmap bitmap) {
        //圓形圖檔寬高
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        //正方形的邊長
        int r = 0;
        //取最短邊做邊長
        if(width > height) {
            r = height;
        } else {
            r = width;
        }
        //建構一個bitmap
        Bitmap backgroundBmp = Bitmap.createBitmap(width,
                 height, Config.ARGB_8888);
        //new一個Canvas,在backgroundBmp上畫圖
        Canvas canvas = new Canvas(backgroundBmp);
        Paint paint = new Paint();
        //設定邊緣光滑,去掉鋸齒
        paint.setAntiAlias(true);
        //寬高相等,即正方形
        RectF rect = new RectF(0, 0, r, r);
        //通過制定的rect畫一個圓角矩形,當圓角X軸方向的半徑等于Y軸方向的半徑時,
        //且都等于r/2時,畫出來的圓角矩形就是圓形
        canvas.drawRoundRect(rect, r/2, r/2, paint);
        //設定當兩個圖形相交時的模式,SRC_IN為取SRC圖形相交的部分,多餘的将被去掉
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        //canvas将bitmap畫在backgroundBmp上
        canvas.drawBitmap(bitmap, null, rect, paint);
        //傳回已經繪畫好的backgroundBmp
        return backgroundBmp;
    }</span>
           

下面解釋一下關鍵的幾行代碼:

<span style="font-family:Microsoft YaHei;font-size:14px;">canvas.drawRoundRect(rect, r/2, r/2, paint);</span>
           

這行代碼是畫一個圓角矩形,X、Y方向的圓角半徑相等時,且長度為正方形邊長的一半時,則畫出來的圓角矩形就是圓,如下圖:

從原理上去了解圓形頭像 Android ImageView圓形頭像 圖檔完全解析

對于這行代碼,大家可以看看這篇文章http://book.51cto.com/art/201204/328272.htm

<span style="font-family:Microsoft YaHei;font-size:14px;">paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));</span>
           

這行代碼是設定圖檔相交時的模式,這篇文章有一張很好的圖說明,http://trylovecatch.iteye.com/blog/1189452

<span style="font-family:Microsoft YaHei;font-size:14px;">canvas.drawBitmap(bitmap, null, rect, paint);</span>
           

而這行代碼則是畫一個bitmap到canvas上面去,官方API:

從原理上去了解圓形頭像 Android ImageView圓形頭像 圖檔完全解析

參數:src 可以為空,不為空時,canvas将bitmap畫到該區域;

參數:dst 不為空,顯示bitmap的顯示區域。

如果src和dst的區域不一樣,那麼bitmap畫的地方和顯示的地方将不一樣,即隻能看到一部分bitmap。