文章來自于:http://my.oschina.net/u/2241960/blog/321024
我們在做項目的時候會用到圓形的圖檔,比如使用者頭像,類似QQ。使用者在用QQ更換頭像的時候,上傳的圖檔都是矩形的,但顯示的時候确是圓形的。
原理:先在canvas上面畫一個圓形,參照圓形的起點坐标、半徑,再畫一個邊長為圓的直徑的bitmap(這個bitmap就是你想畫的圓形頭像),此時圓和bitmap重疊在一起,圓在下面,bitmap在上面,bitmap覆寫着圓(如下圖,其實圓是在bitmap後面的,看不到的。為了形象,我用ps搞了一個半透明圓效果)。
關鍵點來了:這時,圓形和bitmap相交的部分正是圓大小的面積,如果能将bitmap與圓相交之外的部分去掉,那麼我們看到的是不是bitmap的圓形部分?(如下圖藍色部分)
搞清楚原理後,下面我門來看代碼是怎麼實作的。
<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方向的圓角半徑相等時,且長度為正方形邊長的一半時,則畫出來的圓角矩形就是圓,如下圖:
對于這行代碼,大家可以看看這篇文章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:
參數:src 可以為空,不為空時,canvas将bitmap畫到該區域;
參數:dst 不為空,顯示bitmap的顯示區域。
如果src和dst的區域不一樣,那麼bitmap畫的地方和顯示的地方将不一樣,即隻能看到一部分bitmap。