android绘制圆形图片的两种方式示例
程序员文章站
2024-03-31 10:56:40
android绘制圆形图片的两种方式
看下效果先
下面有完整的示例代码
使用bitmapshader(着色器)
我们在绘制view 的时候 就是小学...
android绘制圆形图片的两种方式
看下效果先
下面有完整的示例代码
使用bitmapshader(着色器)
我们在绘制view 的时候 就是小学上美术课 用水彩笔在本子上画画 使用着色器绘制圆形图片最简单的理解方式 就是把bitmap当做一种颜色 设置给paint ,paint都已经有颜色了 你想让它方了,圆了,扁了 还不是看你心情 canvas调用那个方法咯
实现的大致思路如下:
1. 创建一个类 继承imageview 重写ondraw()
2. 获取到bitmap图片
3. 计算图片的缩放比例 使用矩阵matrix 进行缩放
4. 创建bitmapshader着色器 设置缩放矩阵
5. paint设置着色器 绘制
具体实现 注释也标注的很清楚
private void shadercircle(canvas canvas){ //获取drawable drawable resources=getdrawable(); float scale = 1.0f;//缩放比例 int mradius=0;//圆的半径 if (resources instanceof bitmapdrawable){ //获取bitmap bitmap bitmap=((bitmapdrawable) resources).getbitmap(); if (bitmap==null) return; // 获取bitmap宽高中的小值 int minbitmap = math.min(bitmap.getwidth(), bitmap.getheight()); //取view宽高中的小值 尽量保证图片内容的显示 int minvalue=math.min(getwidth(),getheight()); //设置半径 mradius=minvalue/2; //计算缩放比例 一定要*1.0f 因为int之间的计算结果会四舍五入0或1 效果就不美丽了 scale=minvalue*1.0f/minbitmap; //设置缩放比例 matrix.setscale(scale,scale); /** * 创建着色器 设置着色模式 * tilemode的取值有三种: * clamp 拉伸 repeat 重复 mirror 镜像 */ bitmapshader shader=new bitmapshader(bitmap, shader.tilemode.clamp, shader.tilemode.clamp); //设置矩阵 shader.setlocalmatrix(matrix); paint.setshader(shader); canvas.drawcircle(mradius, mradius, mradius, paint); } }
使用xfermode 设置图片相交模式
简单说呢 在一张画布上画了两张图片 这两张图的以怎样的方式显示出来 例如:只显示上层图片,只显示下层图片 ,显示两张图的交集部分 等等等
实现思路
1.创建一个空bitmap 根据这个bitmap创建一个canvas
2.设置canvas透明 画一个想要实现的形状
3.设置图形相交模式
4.获取图片资源 绘制到canvas
实现代码
private bitmap getcirclebitmap(){ drawable drawable=getdrawable(); if (drawable instanceof bitmapdrawable) { paint paint=new paint(); paint.setantialias(true); //获取资源图片 bitmap bitmap = ((bitmapdrawable) drawable).getbitmap(); //创建空位图 bitmap output=bitmap.createbitmap(getwidth(),getheight(),bitmap.config.argb_8888); //创建画板 canvas canvas=new canvas(output); //绘制整个画板为透明 canvas.drawcolor(color.transparent); paint.setcolor(color.white); //绘制圆角图片 if (type==round){ canvas.drawroundrect(new rectf(0, 0, getwidth(), getheight()), mround, mround,paint); }else{ //绘制圆形图片 //取view宽高中的小值 尽量保证图片内容的显示 int minvalue = math.min(getwidth(), getheight()); //设置半径 mradius = minvalue / 2; canvas.drawcircle(mradius,mradius,mradius,paint); } //设置图形相交模式 paint.setxfermode(new porterduffxfermode(porterduff.mode.src_in)); rect src=new rect(0,0,bitmap.getwidth(),bitmap.getheight()); rect dst=new rect(0,0,output.getwidth(),output.getheight()); canvas.drawbitmap(bitmap,src,dst,paint); return output; } return null; }
这个特别经典的图......
porterduff.mode.clear 清除画布上图像 porterduff.mode.src 显示上层图像 porterduff.mode.dst 显示下层图像 porterduff.mode.src_over上下层图像都显示,上层居上显示 porterduff.mode.dst_over 上下层都显示,下层居上显示 porterduff.mode.src_in 取两层图像交集部分只显示上层图像 porterduff.mode.dst_in 取两层图像交集部分,只显示下层图像 porterduff.mode.src_out 取上层图像非交集部分 porterduff.mode.dst_out 取下层图像非交集部分 porterduff.mode.src_atop 取下层图像非交集部分与上层图像交集部分 porterduff.mode.dst_atop 取上层图像非交集部分与下层图像交集部分 porterduff.mode.xor 取两层图像的非交集部分
参考文档
继承imageview完成圆形和圆角图片控件的实现过程(使用着色器)
<declare-styleable name="circleimage"> <attr name="imageround" format="dimension"/> <attr name="imagetype"> <enum name="circle" value="0"/> <enum name="round" value="1"/> </attr> </declare-styleable>
public class circleimage extends imageview { private matrix matrix; private paint paint; private int mround;//圆角度数 private int mradius;//圆的半径 private int type;//控件类型 private final int circle=0;//圆形 private final int round=1;//圆角 public circleimage(context context) { super(context,null); } public circleimage(context context, attributeset attrs) { super(context, attrs); matrix=new matrix(); paint=new paint(); paint.setantialias(true); initattrvalues(context,attrs); } @override protected void ondraw(canvas canvas) { if (getdrawable() == null) { return; } setshader(); if (type==circle){ canvas.drawcircle(mradius, mradius, mradius, paint); }else{ canvas.drawroundrect(new rectf(0, 0, getwidth(), getheight()), mround, mround,paint); } } /** * 初始化属性集合 * @param context * @param attrs */ private void initattrvalues(context context, attributeset attrs){ typedarray typedarray=context.obtainstyledattributes(attrs, r.styleable.circleimage); for (int i=0;i<typedarray.getindexcount();i++){ int index=typedarray.getindex(i); switch (index){ case r.styleable.circleimage_imageround: mround =typedarray.getdimensionpixelsize(index, (int)typedvalue.applydimension(typedvalue.complex_unit_dip,10,getresources().getdisplaymetrics())); break; case r.styleable.circleimage_imagetype: type=typedarray.getint(index,circle); break; } } } /** * 设置着色器 */ private void setshader() { //获取drawable drawable resources=getdrawable(); float scale = 1.0f;//缩放比例 if (resources instanceof bitmapdrawable) { //获取bitmap bitmap bitmap = ((bitmapdrawable) resources).getbitmap(); if (bitmap == null) return; //圆形 if (type==circle){ // 获取bitmap宽高中的小值 int minbitmap = math.min(bitmap.getwidth(), bitmap.getheight()); //取view宽高中的小值 尽量保证图片内容的显示 int minvalue = math.min(getwidth(), getheight()); //设置半径 mradius = minvalue / 2; //计算缩放比例 一定要*1.0f 因为int之间的计算结果会四舍五入0或1 效果就不美丽了 scale = minvalue * 1.0f / minbitmap; }else{ //比较view和图片宽高比例大的 要让缩放后的图片大于view scale = math.max(getwidth() * 1.0f / bitmap.getwidth(), getheight() * 1.0f / bitmap.getheight()); } //设置缩放比例 matrix.setscale(scale, scale); /** * 创建着色器 设置着色模式 * tilemode的取值有三种: * clamp 拉伸 repeat 重复 mirror 镜像 */ bitmapshader shader = new bitmapshader(bitmap, shader.tilemode.clamp, shader.tilemode.clamp); //设置矩阵 shader.setlocalmatrix(matrix); //设置着色 paint.setshader(shader); } } /** * 测试转换效果 没什么卵用 可以删除 * @param event * @return */ @override public boolean ontouchevent(motionevent event) { if (event.getaction()==motionevent.action_down){ if (type==circle){ mround =10; type=round; }else{ type=circle; } invalidate(); } return super.ontouchevent(event); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: Android 实现伸缩布局效果示例代码