欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-03-31 10:56:40
android绘制圆形图片的两种方式 看下效果先 下面有完整的示例代码 使用bitmapshader(着色器) 我们在绘制view 的时候 就是小学...

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。