Android 绘制圆角图片(圆形图片,圆角矩形图片,圆角正方形图片)【转】

来自:http://blog.csdn.net/ywl5320/article/details/38450021

我们在Android应用中经常要绘制圆角的图片来展示一些背景图,但是每次都制作圆角的图片很麻烦,而且重复使用率不高。所以我们最好的就是在应用中根据已有的图片,动态的绘制所需要的圆角图片用于显示。话不多说,让我们先看看效果图:


这是例子中使用到的图片:


怎么样,效果很好吧。

实现绘制圆角图片的原理很简单,就是在程序中动态生成一张Bitmap,然后再用Paint在这张Bitmap中绘制所需的图形(如圆形),再根据paint的setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN))属性设置在Bitmap中画的圆形和所要显示的图片的交集,并取图片部分,那样就生成了圆形的图片。“

其中Mode取值有如下一些值:

[plain]  view plain  copy
  1. 1.PorterDuff.Mode.CLEAR  
  2. 所绘制不会提交到画布上。  
  3.   
  4.   
  5. 2.PorterDuff.Mode.SRC  
  6. 显示上层绘制图片  
  7.   
  8.   
  9. 3.PorterDuff.Mode.DST  
  10. 显示下层绘制图片  
  11.   
  12.   
  13. 4.PorterDuff.Mode.SRC_OVER  
  14. 正常绘制显示,上下层绘制叠盖。  
  15.   
  16.   
  17. 5.PorterDuff.Mode.DST_OVER  
  18. 上下层都显示。下层居上显示。  
  19.   
  20.   
  21. 6.PorterDuff.Mode.SRC_IN  
  22. 取两层绘制交集。显示上层。  
  23.   
  24.   
  25. 7.PorterDuff.Mode.DST_IN  
  26. 取两层绘制交集。显示下层。  
  27.   
  28.   
  29. 8.PorterDuff.Mode.SRC_OUT  
  30. 取上层绘制非交集部分。  
  31.   
  32.   
  33. 9.PorterDuff.Mode.DST_OUT  
  34. 取下层绘制非交集部分。  
  35.   
  36.   
  37. 10.PorterDuff.Mode.SRC_ATOP  
  38. 取下层非交集部分与上层交集部分  
  39.   
  40.   
  41. 11.PorterDuff.Mode.DST_ATOP  
  42. 取上层非交集部分与下层交集部分  
  43.   
  44.   
  45. 12.PorterDuff.Mode.XOR  
  46. 取两层绘制非交集。两层绘制非交集。  
  47.   
  48.   
  49. 13.PorterDuff.Mode.DARKEN  
  50. 上下层都显示。变暗  
  51.   
  52.   
  53. 14.PorterDuff.Mode.LIGHTEN  
  54. 上下层都显示。变量  
  55.   
  56.   
  57. 15.PorterDuff.Mode.MULTIPLY  
  58. 取两层绘制交集  
  59.   
  60.   
  61. 16.PorterDuff.Mode.SCREEN  
  62. 上下层都显示。  

原理就是这样,接下来我们看看示例代码怎么应用:

第一:先看布局文件activity_main.xml

[html]  view plain  copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <ImageView  
  7.         android:id="@+id/source"  
  8.         android:layout_width="100dip"  
  9.         android:layout_height="100dip"  
  10.         android:layout_centerHorizontal="true"  
  11.         android:layout_marginBottom="20dip"  
  12.         android:layout_marginTop="20dip"  
  13.         android:src="@drawable/demo"/>  
  14.       
  15.     <ImageView  
  16.         android:id="@+id/circle"  
  17.         android:layout_width="100dip"  
  18.         android:layout_height="100dip"  
  19.         android:layout_centerHorizontal="true"  
  20.         android:layout_below="@id/source"  
  21.         android:layout_marginBottom="20dip"/>  
  22.     <ImageView  
  23.         android:id="@+id/rect"  
  24.         android:layout_width="100dip"  
  25.         android:layout_height="100dip"  
  26.         android:layout_below="@id/circle"  
  27.         android:layout_centerHorizontal="true"  
  28.         android:layout_marginBottom="20dip"/>  
  29.     <ImageView  
  30.         android:id="@+id/squre"  
  31.         android:layout_width="100dip"  
  32.         android:layout_height="100dip"  
  33.         android:layout_below="@id/rect"  
  34.         android:layout_centerHorizontal="true"/>  
  35.   
  36. </RelativeLayout>  

这里定义了四个Imageview,第一个为原图,第二个为圆形图片,第三个为圆角矩形,第四个为圆角正方形。


第二:为了节省空间,我就把生成图片的代码写在了MainActivity中,如下,注释都很清楚:

[java]  view plain  copy
  1. package com.demo.imagetype;  
  2.   
  3. import android.app.Activity;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.Bitmap.Config;  
  6. import android.graphics.Canvas;  
  7. import android.graphics.Paint;  
  8. import android.graphics.PorterDuffXfermode;  
  9. import android.graphics.RectF;  
  10. import android.graphics.drawable.BitmapDrawable;  
  11. import android.graphics.drawable.Drawable;  
  12. import android.os.Bundle;  
  13. import android.widget.ImageView;  
  14.   
  15. public class MainActivity extends Activity {  
  16.     private ImageView circle;  
  17.     private ImageView rect;  
  18.     private ImageView squre;  
  19.   
  20.     @Override  
  21.     protected void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.activity_main);  
  24.         circle = (ImageView)findViewById(R.id.circle);  
  25.         rect = (ImageView)findViewById(R.id.rect);  
  26.         squre = (ImageView)findViewById(R.id.squre);  
  27.           
  28.         /** 获取图片资源并转换为 Bitmap类型 */  
  29.         Drawable drawable = getResources().getDrawable(R.drawable.demo);   
  30.         BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;    
  31.         Bitmap bitmap = bitmapDrawable.getBitmap();  
  32.           
  33.         circle.setImageBitmap(getCircleBitmap(bitmap));  
  34.         rect.setImageBitmap(drawRect(bitmap, 80));  
  35.         squre.setImageBitmap(drawSqureRect(bitmap, 80));  
  36.     }  
  37.       
  38.       
  39.       
  40.     /** 
  41.      * 绘制圆形 
  42.      * @param source 
  43.      * @return 
  44.      */  
  45.     public static Bitmap getCircleBitmap(Bitmap source)  
  46.     {  
  47.         // 以最小的边为圆的半径  
  48.         int min = 0;  
  49.         if(source.getWidth() < source.getHeight())  
  50.         {  
  51.             min = source.getWidth();  
  52.         }  
  53.         else  
  54.         {  
  55.             min = source.getHeight();  
  56.         }  
  57.   
  58.         // 获取图片的中心点,使之与圆形的中心点重合,才不会让图片出现偏移  
  59.         int x = 0;   
  60.         int y = 0;  
  61.         if(source.getWidth() > min)  
  62.         {  
  63.             x = -(source.getWidth() - min);  
  64.         }  
  65.         else  
  66.         {  
  67.             x = min - source.getWidth();  
  68.         }  
  69.         if(source.getHeight() > min)  
  70.         {  
  71.             y = -(source.getHeight() - min);  
  72.         }  
  73.         else  
  74.         {  
  75.             y = min - source.getHeight();  
  76.         }  
  77.   
  78.         // 创建画笔  
  79.         final Paint paint = new Paint();  
  80.         paint.setAntiAlias(true);  
  81.         // 以新建的bitmap创建画布  
  82.         Bitmap bitmap = Bitmap.createBitmap(min, min, Config.ARGB_8888);  
  83.         Canvas canvas = new Canvas(bitmap);  
  84.           
  85.         // 以图片最小边为直径绘制圆形区域  
  86.         canvas.drawCircle(min / 2, min / 2, min / 2, paint);  
  87.           
  88.         // 设置圆形区域与要显示的图片相交,并取相交区域的图片为结果图片  
  89.         // Mode.SRC_IN:取两层绘制交集。显示上层。  
  90.         paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN));  
  91.         canvas.drawBitmap(source, x/2, y/2, paint);  
  92.         // 返回生成的bitmap,bitmap就是圆形图片  
  93.         return bitmap;  
  94.     }  
  95.       
  96.     /** 
  97.      * 绘制圆角矩形 
  98.      * @param source 
  99.      * @param radius 
  100.      * @return 
  101.      */  
  102.     public Bitmap drawRect(Bitmap source, int radius)  
  103.     {  
  104.         // 得到要绘制的图片的长和宽,用来绘制圆角矩形的长和宽  
  105.         int width = source.getWidth();  
  106.         int height = source.getHeight();  
  107.           
  108.         final Paint paint = new Paint();  
  109.         paint.setAntiAlias(true);  
  110.           
  111.         Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);  
  112.         Canvas canvas = new Canvas(bitmap);  
  113.           
  114.         RectF rect = new RectF(00, width, height);  
  115.         canvas.drawRoundRect(rect, radius, radius, paint);  
  116.           
  117.         paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN));  
  118.         canvas.drawBitmap(source, 00, paint);  
  119.         return bitmap;  
  120.     }  
  121.       
  122.     /** 
  123.      * 绘制圆角正方形 
  124.      * @param source 
  125.      * @param radius 
  126.      * @return 
  127.      */  
  128.     public Bitmap drawSqureRect(Bitmap source, int radius)  
  129.     {  
  130.         int min = 0;//获取最小的边长  
  131.         if(source.getWidth() < source.getHeight())  
  132.         {  
  133.             min = source.getWidth();  
  134.         }  
  135.         else  
  136.         {  
  137.             min = source.getHeight();  
  138.         }  
  139.           
  140.         int x = 0;//绘制中心的x坐标  
  141.         int y = 0;//绘制中心的y坐标  
  142.         if(source.getWidth() > min)  
  143.         {  
  144.             x = -(source.getWidth() - min);  
  145.         }  
  146.         else  
  147.         {  
  148.             x = min - source.getWidth();  
  149.         }  
  150.           
  151.         if(source.getHeight() > min)  
  152.         {  
  153.             y = -(source.getHeight() - min);  
  154.         }  
  155.         else  
  156.         {  
  157.             y = min - source.getHeight();  
  158.         }  
  159.           
  160.         final Paint paint = new Paint();  
  161.         paint.setAntiAlias(true);  
  162.           
  163.         Bitmap bitmap = Bitmap.createBitmap(min, min, Config.ARGB_8888);  
  164.         Canvas canvas = new Canvas(bitmap);  
  165.         RectF rect = new RectF(00, min, min);  
  166.         canvas.drawRoundRect(rect, radius, radius, paint);  
  167.         paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN));  
  168.         canvas.drawBitmap(source, x/2, y/2, paint);//将要绘制的图片中心移动到画布中心  
  169.         return bitmap;  
  170.     }  
  171. }  
  172.   
  173. /** 
  174.  * 1.PorterDuff.Mode.CLEAR 
  175. 所绘制不会提交到画布上。 
  176.  
  177. 2.PorterDuff.Mode.SRC 
  178. 显示上层绘制图片 
  179.  
  180. 3.PorterDuff.Mode.DST 
  181. 显示下层绘制图片 
  182.  
  183. 4.PorterDuff.Mode.SRC_OVER 
  184. 正常绘制显示,上下层绘制叠盖。 
  185.  
  186. 5.PorterDuff.Mode.DST_OVER 
  187. 上下层都显示。下层居上显示。 
  188.  
  189. 6.PorterDuff.Mode.SRC_IN 
  190. 取两层绘制交集。显示上层。 
  191.  
  192. 7.PorterDuff.Mode.DST_IN 
  193. 取两层绘制交集。显示下层。 
  194.  
  195. 8.PorterDuff.Mode.SRC_OUT 
  196. 取上层绘制非交集部分。 
  197.  
  198. 9.PorterDuff.Mode.DST_OUT 
  199. 取下层绘制非交集部分。 
  200.  
  201. 10.PorterDuff.Mode.SRC_ATOP 
  202. 取下层非交集部分与上层交集部分 
  203.  
  204. 11.PorterDuff.Mode.DST_ATOP 
  205. 取上层非交集部分与下层交集部分 
  206.  
  207. 12.PorterDuff.Mode.XOR 
  208. 取两层绘制非交集。两层绘制非交集。 
  209.  
  210. 13.PorterDuff.Mode.DARKEN 
  211. 上下层都显示。变暗 
  212.  
  213. 14.PorterDuff.Mode.LIGHTEN 
  214. 上下层都显示。变量 
  215.  
  216. 15.PorterDuff.Mode.MULTIPLY 
  217. 取两层绘制交集 
  218.  
  219. 16.PorterDuff.Mode.SCREEN 
  220. 上下层都显示。 
  221. **/  

其中在绘制圆角矩形的方法中第二个参数就是圆角的弧度,大家可以自己修改试试,看效果如何。好了,虽然代码不多也不复杂,但是确实很实用。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值