方法1: 裁剪Bitmap,设置ImageView src

主要是取缩放/裁剪Bitmap,然后设置给ImageView src或者background
实际使用中发现系统app 的ICON 比较特殊,比如时钟/日历是动态的,把通过PackageManager 拿到的Drawable 转成BitmapDrawable 后显示出来的图片和在桌面看到的不一样的.具体为什么Drawable 转成BitmapDrawable后有这个异常现象暂时没有去研究.后面找时间去研究.

public static Bitmap cropBitmap(Bitmap bitmap) {//从中间截取一个正方形int w = bitmap.getWidth(); // 得到图片的宽,高int h = bitmap.getHeight();int cropWidth = w >= h ? h : w;// 裁切后所取的正方形区域边长return Bitmap.createBitmap(bitmap, (bitmap.getWidth() - cropWidth) / 2,(bitmap.getHeight() - cropWidth) / 2, cropWidth, cropWidth);}public static Bitmap getCircleBitmap(Bitmap bitmap) {//把图片裁剪成圆形if (bitmap == null) {return null;}bitmap = cropBitmap(bitmap);//裁剪成正方形try {Bitmap circleBitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(circleBitmap);final Paint paint = new Paint();final Rect rect = new Rect(0, 0, bitmap.getWidth(),bitmap.getHeight());final RectF rectF = new RectF(new Rect(0, 0, bitmap.getWidth(),bitmap.getHeight()));float roundPx = 0.0f;roundPx = bitmap.getWidth();paint.setAntiAlias(true);canvas.drawARGB(0, 0, 0, 0);paint.setColor(Color.WHITE);canvas.drawRoundRect(rectF, roundPx, roundPx, paint);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));final Rect src = new Rect(0, 0, bitmap.getWidth(),bitmap.getHeight());canvas.drawBitmap(bitmap, src, rect, paint);return circleBitmap;} catch (Exception e) {return bitmap;}}

方法2:自定义ImageView,利用Canvas 的clipPath() 

实际效果出来后发现有锯齿,考虑通过Paint的PorterDuff.Mode替代Path实现所需要的效果.
实际测试的时候为了简单,直接在xml 里面固定了view 宽和高度是200dp.

public class ClipPathCircleImage extends ImageView {private int width;private int height;private Path path;public ClipPathCircleImage(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);path = new Path();}@Overrideprotected void onDraw(Canvas canvas) {canvas.save();path.reset();path.addCircle(width/2, height/2, width/2, Path.Direction.CCW);//CCW:逆时针,这里是一个简单的园,无影响canvas.clipPath(path);super.onDraw(canvas);canvas.restore();//使用Path时,如果不与Paint进行共同操作,无法解决抗锯齿问题。//这时候只能使用Paint的PorterDuff.Mode替代Path实现所需要的效果}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);width = w;height = h;}public ClipPathCircleImage(Context context, AttributeSet attrs, int defStyleAttr) {this(context, attrs, defStyleAttr, 0);}public ClipPathCircleImage(Context context, AttributeSet attrs) {this(context, attrs, 0);}public ClipPathCircleImage(Context context) {this(context, null);}}

方法3:自定义ImageView,利用Paint的PorterDuff.Mode替代Path实现所需要的效果

public class CircleImage extends ImageView {private int width;private int height;private Path path;private Path srcPath;private Paint paint;private RectF srcRectF;private Xfermode xfermode;public CircleImage(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);path = new Path();srcPath = new Path();paint= new Paint();xfermode = new PorterDuffXfermode(Mode.DST_OUT);}@Overrideprotected void onDraw(Canvas canvas) {canvas.saveLayer(srcRectF, null, Canvas.ALL_SAVE_FLAG);super.onDraw(canvas);// ImageView自身的绘制流程,即绘制图片path.reset();paint.reset();path.addCircle(width/2, height/2, width/2, Path.Direction.CW);////CW:顺时针,这里是一个简单的园,无影响paint.setStyle(Style.FILL);//Paint 默认就是fill style,不设置也可以paint.setAntiAlias(true);//抗锯齿paint.setXfermode(xfermode);//设置混合模式 DST_OUT srcPath.addRect(srcRectF, Direction.CCW);srcPath.op(path, Path.Op.DIFFERENCE);canvas.drawPath(srcPath, paint);paint.setXfermode(null);canvas.restore();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);width = w;height = h;srcRectF =  new RectF(0, 0, w, h);}public CircleImage(Context context, AttributeSet attrs, int defStyleAttr) {this(context, attrs, defStyleAttr, 0);}public CircleImage(Context context, AttributeSet attrs) {this(context, attrs, 0);}public CircleImage(Context context) {this(context, null);}

具体效果如下:
第一个是未处理的;
第2个是Canvas.clipPatch() 实现的,有锯齿.
第3个是通过Paint的PorterDuff.Mode替代Path实现

 

更多相关文章

  1. Android(安卓)在TextView 中显示图片的4种方式
  2. Android(安卓)7.0 之 FileProvider运用:拍照获取头像并设置
  3. 自定义View之圆角图片
  4. Android(安卓)轮播图实现(新手易懂)
  5. Android(安卓)Translucent System Bar 的最佳实践
  6. 基于WiEngine游戏引擎--背景移动
  7. Android对SlidingDraw组件修改
  8. Android中对于Bitmap的处理
  9. Android阴影效果与CardView版本适配的细节问题

随机推荐

  1. 【java工具类】网站安全---将特殊字符编
  2. mvn依赖的jar,在项目中无法引用,求大神指点
  3. javascript(六)js事件绑定浏览器兼容解决方
  4. java httpclient访问某些网页报403错误
  5. 使用js模仿java的实体类对类/对象进行get
  6. Java——IO类,字节流读数据
  7. 关于的写法
  8. 9.JAVA-抽象类定义
  9. Java多线程编程
  10. 用javascript怎么取到当前月第一天、最后