Android圆角图片最佳方案 转载于:http://blog.csdn.net/zenip/article/details/8766263
关于“Android圆角图片”,网上可以搜索到大把代码示例。而这些示例千篇一律过于单一,而 且对内存性能没有进行较好分析 本文将总结网上流行的几种圆角图片方案,进行性能与内存的分析,并得出最佳方案。(PS:本人初出江湖,高手勿喷)。

基础脑补:

位图:256位对比32位,存储信息量大但是占用内存也大, 图像质量较高。

ARGB:A=Alpha, R=Red, G=Green,B=Blue

ARGB_8888:8888意味着它们都用8个位来显示,32位的位图。

ARGB_4444:逻辑同上,16位的位图。

RGB_565:逻辑同上,16位的位图。

ALPHA_8:用8个位来表示透明度,8位的位图。


圆角方案一: PortrDuffXfermode拷贝Bitmap

代码:

[java] view plain copy
  1. publicstaticBitmapgetRoundedCornerBitmap(Bitmapbitmap,intpixels){
  2. Bitmapoutput=Bitmap.createBitmap(bitmap.getWidth(),bitmap
  3. .getHeight(),Config.ARGB_8888);
  4. Canvascanvas=newCanvas(output);
  5. finalintcolor=0xff424242;
  6. finalPaintpaint=newPaint();
  7. finalRectrect=newRect(0,0,bitmap.getWidth(),bitmap.getHeight());
  8. finalRectFrectF=newRectF(rect);
  9. finalfloatroundPx=pixels;//圆角
  10. paint.setAntiAlias(true);
  11. canvas.drawARGB(0,0,0,0);
  12. paint.setColor(color);
  13. canvas.drawRoundRect(rectF,roundPx,roundPx,paint);
  14. paint.setXfermode(newPorterDuffXfermode(Mode.SRC_IN));//Mode.SRC_IN用前面画的“圆角矩形”对bitmap进行裁剪。
  15. canvas.drawBitmap(bitmap,rect,rect,paint);
  16. returnoutput;
  17. }

大概思路:从内存中创建一张同样大小的位图output,并使用canvas技术对图片进行裁剪并绘制的output中。

疑点集合:为啥采用0xff424242?

优点:使用简单。

缺点:方法栈内存消耗大,在方法消耗多1倍原有的bitmap内存且性能低下,在图片较大时有OOM的可能。 不适应ImageView,无法与ImageView的scaleType很好的工作,尤其是图片较小的情况下,圆角效果将破坏整个图像的呈现。

圆角方案二:PortrDuffXfermodeImageView

覆盖ImageView的onDraw方法。 [java] view plain copy
  1. @Override
  2. protectedvoidonDraw(Canvascanvas){
  3. DrawablemaiDrawable=getDrawable();
  4. floatmCornerRadius=6*getContext().getResources().getDisplayMetrics().density;//圆角半径
  5. if(maiDrawableinstanceofBitmapDrawable&&mCornerRadius>0){
  6. Paintpaint=((BitmapDrawable)maiDrawable).getPaint();
  7. finalintcolor=0xff000000;
  8. finalRectFrectF=newRectF(0,0,getWidth(),getHeight());
  9. intsaveCount=canvas.saveLayer(rectF,null,Canvas.MATRIX_SAVE_FLAG|Canvas.CLIP_SAVE_FLAG|Canvas.HAS_ALPHA_LAYER_SAVE_FLAG|Canvas.FULL_COLOR_LAYER_SAVE_FLAG
  10. |Canvas.CLIP_TO_LAYER_SAVE_FLAG);
  11. paint.setAntiAlias(true);
  12. canvas.drawARGB(0,0,0,0);
  13. paint.setColor(color);
  14. canvas.drawRoundRect(rectF,mCornerRadius,mCornerRadius,paint);
  15. XfermodeoldMode=paint.getXfermode();
  16. paint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.SRC_IN));
  17. super.onDraw(canvas);
  18. paint.setXfermode(oldMode);
  19. canvas.restoreToCount(saveCount);
  20. }else{
  21. super.onDraw(canvas);
  22. }
  23. }

大概思路:ImageView会将src图片最终转化位一个drawable,通过getDrawable()获取该drawable,并获取其画笔。通过saveLayer。我们可以创建一个新图层,并在上面绘制。 对画笔使用PorterDuffXfermode。从而将圆角效果绘制出来。

优点:与前者相比,能很好的兼容ImageView的scaleType。

缺点:运行速度较为缓慢,由于onDraw运行在ui线程,PorterDuffXfermode是采用SRC_IN的方式进行图像裁剪,这种裁剪方式的速度具体视图像大小质量而视,使用不当容易Anr。

(ps: 个人猜测,PorterDuffXfermode采用逐个字节处理的方式执行,想想如果图像越大,字节数量越多,那花费时间势必超过5秒。)

圆角方案三:使用Path进行圆角边缘化

继承ImageView增加以下方法。

[java] view plain copy
  1. @TargetApi(11)
  2. privatevoidinit(){
  3. setLayerType(View.LAYER_TYPE_SOFTWARE,null);
  4. this.mMaskPaint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.CLEAR));
  5. }
  6. privatevoidgenerateMaskPath(intwidth,intheight){
  7. this.mMaskPath=newPath();
  8. this.mMaskPath.addRoundRect(newRectF(0.0F,0.0F,width,height),this.mCornerRadius,this.mCornerRadius,Path.Direction.CW);
  9. this.mMaskPath.setFillType(Path.FillType.INVERSE_WINDING);
  10. }
  11. @Override
  12. protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){
  13. super.onSizeChanged(w,h,oldw,oldh);
  14. if((w!=oldw)||(h!=oldh))
  15. generateMaskPath(w,h);
  16. }
  17. protectedvoidonDraw(Canvascanvas){
  18. //保存当前layer的透明橡树到离屏缓冲区。并新创建一个透明度爲255的新layer
  19. intsaveCount=canvas.saveLayerAlpha(0.0F,0.0F,canvas.getWidth(),canvas.getHeight(),
  20. 255,Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
  21. super.onDraw(canvas);
  22. if(this.mMaskPath!=null){
  23. canvas.drawPath(this.mMaskPath,this.mMaskPaint);
  24. }
  25. canvas.restoreToCount(saveCount);
  26. }

大概思路:创建以“圆角矩形”为结构的Path,并利用Path.FillType.INVERSE_WINDING反选“圆角矩形区域”。从而达到圆角边缘化的效果。

优点:与前者相比,由于不需要对ImageView的图片进行字节操作,所以速度快许多,而且在动画表现上十分平滑。

缺点:暂无。


更多相关文章

  1. android学习——GridView实现主界面布局
  2. Android拼接合并图片生成长图
  3. android通过Base64往服务器上传图片和对象
  4. android中ImageView属性及其详解
  5. Android(安卓)SQlite数据库的使用(一)-一学就会android数据库
  6. 关于在Android(安卓)Studio中使用Assets目录下的资源的问题
  7. Android性能优化《Android开发艺术探索》笔记
  8. Android极致优化
  9. Android――Android(安卓)lint工具项目资源清理详解

随机推荐

  1. Android经典项目开发之天气APP实例分享
  2. 【android免root脚本制作】基于控件的操
  3. Android(安卓)7.1添加一个 系统底层服务
  4. Android(安卓)利用SurfaceView实现一个简
  5. Android(安卓)OpenGL纹理
  6. 性能怪兽的诞生日记:Kindle Fire HDX 8.9
  7. 自定义Drawable实现灵动的红鲤鱼动画(上篇
  8. Android(安卓)ConstraintLayout百分比布
  9. Android中实现「类方法指令抽取方式」加
  10. 从HTML5统治世界的说法来看Native APP 和