软件编程
位置:首页>> 软件编程>> Android编程>> android绘制圆形图片的两种方式示例

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

作者:S丶black  发布时间:2021-10-11 13:17:28 

标签:android,绘制,圆形

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){
   //获取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;

}

这个特别经典的图......

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


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);
 }
}

来源:http://www.cnblogs.com/r-decade/p/6250450.html

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com