这篇博客给大家带来使用xfermode实现圆形图像。先看效果:

这里说下原理,先看下图:

这里src和dst分别表示不同的bitmap,上面的图片有16种类型,分别表示不同情况下的交集,这里我们需要使用的是两个交集部分,试想一下,我们先绘制一个圆,然后绘制一个图片,此时如果圆的大小小于图片的大小,那么图片的交集就是该圆形了,此时使用SrcIn或者DstIn这两种模式就可以过滤出需要的图形了,其实SrcIn或者DstIn是没有什么区别的,无非就是图像先绘制而已。好了,下面看具体的实现:

自定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources><attr name="circle_image_radius" format="dimension" /><attr name="round_image_radius" format="dimension" /><attr name="border_width" format="dimension"/><attr name="is_border" format="boolean"/><attr name="imagetype"><enum name="circle" value="0" /><enum name="round" value="1" /></attr><declare-styleable name="selfimage"><attr name="circle_image_radius" /><attr name="round_image_radius" /><attr name="border_width"/><attr name="is_border"/><attr name="imagetype" /></declare-styleable></resources>

这里:

  • circle_image_radius 表示圆形图像的半径
  • round_image_radius 表示圆角矩形的弧度
  • is_border 表示是否有边框
  • imagetype 表示是哪一种类型,circle或者round

获取自定义属性的值

首先新建类CircleImage继承自View,在构造方法中获取自定义的属性值:

//获取自定义的属性的值TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.selfimage,defStyleAttr,0);int count = array.getIndexCount();for (int i = 0; i < count; i++) {int attr = array.getIndex(i);switch (attr) {case R.styleable.selfimage_circle_image_radius:mCircleImageRadius = array.getDimensionPixelSize(attr,40);break;case R.styleable.selfimage_round_image_radius:mRoundImageRadius = array.getDimensionPixelSize(attr, 0);break;case R.styleable.selfimage_imagetype:mImageType = array.getInt(R.styleable.selfimage_imagetype, 0);break;case R.styleable.selfimage_is_border:mIsBorder = array.getBoolean(attr, false);break;case R.styleable.selfimage_border_width:mBorderWitdh = array.getDimensionPixelSize(attr, 12);break;default:break;}}array.recycle();

重写onDraw方法

我们需要在onDraw方法中进行具体的绘制工作。

int width = getWidth();
int height = getHeight();if (CIRCLE_TYPE == mImageType) {//绘制圆形图片//创建一个和原始view大小相同的bitmapBitmap des  = Bitmap.createBitmap(width, height,Config.ARGB_8888);//根据该bitmap创建一个画布Canvas drawCanvas = new Canvas(des);//根据view的宽高,获取圆形图片的半径//          int radius = Math.min(width, height) / 2;//绘制一个圆drawCanvas.drawCircle(width / 2, height/ 2, mCircleImageRadius, mPaint);//设置setXfermodemPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//将src图像使用设置好的xfermode,绘制到当前des中drawCanvas.drawBitmap(mBitmap, 0, 0, mPaint);//将des 绘制到原始的canvas中canvas.drawBitmap(des, 0, 0,null);if (mIsBorder) {//如果有边框,则设置边框mPaint.setStrokeWidth(mBorderWitdh);mPaint.setColor(Color.RED);mPaint.setAntiAlias(true);mPaint.setStyle(Paint.Style.STROKE);canvas.drawCircle(width / 2, height/ 2, mCircleImageRadius+mBorderWitdh,mPaint);}}if (ROUND_TYPE == mImageType) {//绘制矩形图片Bitmap des = Bitmap.createBitmap(width, height,Config.ARGB_8888);Canvas drawCanvas = new Canvas(des);RectF rectF = new RectF(0,0,width,height);drawCanvas.drawRoundRect(rectF, 12,12,mPaint);mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));drawCanvas.drawBitmap(mBitmap, 0, 0, mPaint);canvas.drawBitmap(des, 0, 0,null);
}

首先使用getWidth()和getHeight()获取到当前view的宽和高。然后根据获取到的自定义属性mImageType的类型判断是是圆形还是圆角矩形。绘制步骤如下:

  • 首先创建一个和当前view大小相同的des
  • 创建一个和当前bitmap相同大小的drawCanvas
  • 使用创建好的drawCanvas绘制我们需要的图形
  • 为Paint设置setXfermode,这里使用到的是PorterDuffXfermode类
  • 将需要显示的bitmap图片绘制到drawCanvas中
  • 使用canvas绘制des
if (mIsBorder) {//如果有边框,则设置边框mPaint.setStrokeWidth(mBorderWitdh);mPaint.setColor(Color.RED);mPaint.setAntiAlias(true);mPaint.setStyle(Paint.Style.STROKE);canvas.drawCircle(width / 2, height/ 2, mCircleImageRadius+mBorderWitdh,mPaint);
}

可以看到这里绘制边框无非就是在图片外边在绘制一个圆圈。该圆圈的半径是mBorderWitdh,即自定义的属性。

在布局中加载自定义view

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:pro="http://schemas.android.com/apk/res/com.example.circleimage"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical" ><com.example.circleimage.CircleImageandroid:layout_width="120dp"android:layout_height="120dp"pro:circle_image_radius="60dp"pro:imagetype="circle" /><com.example.circleimage.CircleImageandroid:layout_width="120dp"android:layout_height="120dp"pro:border_width="2dp"pro:circle_image_radius="55dp"pro:imagetype="circle"pro:is_border="true" /><com.example.circleimage.CircleImageandroid:layout_width="130dp"android:layout_height="100dp"pro:imagetype="round"pro:round_image_radius="16dp"/></LinearLayout>

ok,通过Xfermode实现自定义圆形图像就到这里了,希望大家喜欢。

源码下载

android自定义圆形图像相关推荐

  1. Android自定义圆形进度条

    Android自定义圆形进度条 github地址:https://github.com/opq1289/CircleProgressView 效果图: 无动画: 有动画: 整圆: 切割圆: 具体步骤: ...

  2. Android实现圆形图像的两种方法(Glide和Picasso)

    Android实现圆形图像的两种方法 先上效果图 Glide Picasso CircleTransform.java(圆形图片工具类) 先上效果图 Glide 在app的build.gradle中引 ...

  3. Android 自定义圆形图片 CircleImageView

    1.效果预览 1.1.布局中写自定义圆形图片的路径即可 1.2.然后看一看图片效果 1.3.原图是这样的 @mipmap/ic_launcher 2.使用过程 2.1.CircleImageView源 ...

  4. Android 自定义圆形图片

    代码注释很多,简单说下思路,然后直接贴代码 1.截取选定图片中间区域(宽等于高的正方形) 2.按照控件大小进行缩放 3.画圆,设置paint.setXfermode(new PorterDuffXfe ...

  5. android 自定义圆形头像,android自定义圆形头像

    这几天看了项目框架里面的圆形头像,发现其实这个东西并不是很难的东西,学会了原理,无论圆形头像,五角星头像都可以实现. 目前我上传的Demo里用了两种实现方式,那么我们分别来讲讲这两种实现方式: Bit ...

  6. android小球移动代码,Android自定义圆形View实现小球跟随手指移动效果

    本文实例为大家分享了Android实现小球跟随手指移动效果的具体代码,供大家参考,具体内容如下 一. 需求功能 手指在屏幕上滑动,红色的小球始终跟随手指移动. 实现的思路: 1)自定义View,在on ...

  7. html5跟随手指的小球,Android自定义圆形View实现小球跟随手指移动效果(详细介绍)...

    一. 需求功能 手指在屏幕上滑动,红色的小球始终跟随手指移动. 实现的思路: 1)自定义View,在onDraw中画圆作为小球: 2)重写自定义View的onTouchEvent方法,记录触屏坐标,用 ...

  8. android自定义圆形进度条,实现动态画圆效果

    自定义圆形进度条效果图如下:应用场景如动态显示分数等. view的自定义属性如下attr.xml <?xml version="1.0" encoding="UTF ...

  9. android 自定义圆形pop,Android布局自定义Shap圆形ImageView可以单独设置背景与图片...

    一.图片预览: 一.实现功能: 需求要实现布局中为圆形图片,图片背景与图标分开且合并到一个ImageView. 二.具体实现: XML中布局中定义ImageView,关健设置两个参数 Android: ...

最新文章

  1. 基于AOA协议的android USB通信
  2. 【Qt】Qt再学习(九):并发 QtConcurrent、QFuture、QFutureWatcher
  3. 移动apn接入点哪个快_移动4g网速最快接入点_2020移动最佳APN接入点
  4. Ubuntu 上安装rust
  5. 在Spark中自定义Kryo序列化输入输出API(转)
  6. 不兼容结构的协调——适配器模式
  7. Cannot find source code based button in SE24 - modification assistant
  8. 登和平视显示无法连接服务器,提醒信息的推送方法和装置、平视显示器HUD及服务器...
  9. Java—synchronized和ReentrantLock锁详解
  10. JQuery ajax返回JSON时的处理方式
  11. win11正式版如何安装安卓app windows11正式版安装安卓app的步骤方法
  12. python语言要多久_怎么自学python,大概要多久?
  13. c语言 博客园,C语言l|博客园作业10
  14. 无公式搞懂GMSK调制原理,附详细注释的matlab GMSK调制解调原理仿真源码
  15. 解读国密非对称加密算法SM2
  16. warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]错误
  17. SpringBoot入门-统一错误码
  18. 国际化的locale类详解
  19. telegram协议构架能实现朋友圈或者新浪微博功能么?
  20. 腾讯两大社交巨头败了, 瓦次普才是社交APP的真霸主, 用户比微信多5亿

热门文章

  1. OSGI的建筑学模拟
  2. html5如何利用rem实现自适应布局,使用Rem布局实现自适应
  3. 网红直播学习:VLC如何播放灵派直播编码器SRT流
  4. 堡垒前线辅助游戏错误操作 常见错误介绍
  5. java 递归10 28_如何利用Java递归解决“九连环”公式
  6. 高可用(keepalived)部署方案
  7. python+django+vue图书馆选座系统pycharm源码lw
  8. 解决在spring配置文件中包扫描无效问题
  9. ffmpeg 取消打印信息
  10. 香港旅游六大热门目的地推荐