Welcome

首页 / 移动开发 / Android / android绘制圆形图片的两种方式示例

android绘制圆形图片的两种方式

看下效果先



下面有完整的示例代码
使用BitmapShader(着色器)
我们在绘制view 的时候 就是小学上美术课 用水彩笔在本子上画画 使用着色器绘制圆形图片最简单的理解方式 就是把bitmap当做一种颜色 设置给paint ,paint都已经有颜色了 你想让它方了,圆了,扁了 还不是看你心情 canvas调用那个方法咯
实现的大致思路如下:

1. 创建一个类 继承imageView 重写onDraw()

2. 获取到bitmap图片

3. 计算图片的缩放比例 使用矩阵matrix 进行缩放

4. 创建BitmapShader着色器 设置缩放矩阵

5. paint设置着色器 绘制
具体实现 注释也标注的很清楚

private void shaderCircle(Canvas canvas){//获取DrawableDrawable resources=getDrawable();float scale = 1.0f;//缩放比例int mRadius=0;//圆的半径if (resources instanceof BitmapDrawable){//获取bitmapBitmap 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);}@Overrideprotected 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() {//获取DrawableDrawable resources=getDrawable();float scale = 1.0f;//缩放比例if (resources instanceof BitmapDrawable) {//获取bitmapBitmap 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和图片宽高比例大的 要让缩放后的图片大于viewscale = 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 */@Overridepublic 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);}}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。