您现在的位置是:首页 > 文章详情

android 通过修改图片像素实现CircleImageView

日期:2019-04-13点击:258

CircleImageView实现方法有很多种,各有优缺点,因此需要按照不同的场景使用。我们今天使用修改图片像素的方法实现CircleImageView,主要知识点无非是勾股定理和点到圆形的距离。

素材图片:

 

效果如下:

 

1、clipPath裁剪画布

该方法支持的最小版本是Android 4.3(API Level 18),方便快捷,但是不支持硬件加,此外也存在Path既有的缺点,不支持抗锯齿。

 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pic); mPath = new Path(); mPath.addCircle(mBitmap.getWidth() / 2, mBitmap.getHeight() / 2, mBitmap.getWidth() / 2, Path.Direction.CCW); canvas.clipPath(mPath); canvas.drawBitmap(mBitmap, 0, 0, paint); } 

 

2、使用PorterDuffXfermode

PorterDuffXfermode是Android主流的图片合成工具,支持模式多,稳定性强,效果好,质量高,支持抗锯齿备受广大开发者喜爱,可以说是很多应用开发的首选。缺点是难度学习有些高,另外比较占内存。

 /** * 绘制圆形图片 * */ @Override protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (null != drawable) { Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); Bitmap b = getCircleBitmap(bitmap); final Rect rectSrc = new Rect(0, 0, b.getWidth(), b.getHeight()); final Rect rectDest = new Rect(0,0,getWidth(),getHeight()); paint.reset(); canvas.drawBitmap(b, rectSrc, rectDest, paint); } else { super.onDraw(canvas); } } /** * 获取圆形图片方法 * @param bitmap * @param pixels * @return Bitmap */ private Bitmap getCircleBitmap(Bitmap bitmap) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); paint.setAntiAlias(true); canvas.drawColor(Color.TRANSPARENT); paint.setColor(color); int x = bitmap.getWidth(); canvas.drawCircle(x / 2, x / 2, x / 2, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } 

4、设置画笔Paint的Shader,然后用该画笔绘制圆形图片

该方法是Glide和picasso使用的方法,用法简单便捷,占内占有率处于中等水平。

 @Override protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (null != drawable) { Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); Bitmap b = transform(bitmap); final Rect rectSrc = new Rect(0, 0, b.getWidth(), b.getHeight()); final Rect rectDest = new Rect(0,0,getWidth(),getHeight()); paint.reset(); canvas.drawBitmap(b, rectSrc, rectDest, paint); } else { super.onDraw(canvas); } } public Bitmap transform(Bitmap source) { int size = Math.min(source.getWidth(), source.getHeight()); int x = (source.getWidth() - size) / 2; int y = (source.getHeight() - size) / 2; Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size); if (squaredBitmap != source) { source.recycle(); } Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig()); Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP); float mScale = (mRadius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWidth()); Matrix matrix = new Matrix(); matrix.setScale(mScale, mScale); bitmapShader.setLocalMatrix(matrix); paint.setShader(shader); paint.setAntiAlias(true); float r = size / 2f; canvas.drawCircle(r, r, r, paint); squaredBitmap.recycle(); return bitmap; } 

5、修改像素

该方法无法支持抗锯齿,并且不支持Bitmap.Config.HARDWARE格式的bitmap,但用法简单,内存占有率同样处于比较低。

public class CircleImageView extends AppCompatImageView { public CircleImageView(Context context) { this(context,null); } public CircleImageView(Context context, AttributeSet attrs) { this(context, attrs,0); } public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void onDraw(Canvas canvas) { int width = getWidth(); int height = getHeight(); int minSize = Math.min(width,height)/2; Drawable drawable = getDrawable(); if(drawable!=null && minSize!=0) { if(Math.min(drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight())==0) { return; } int intrinsicWidth = drawable.getIntrinsicWidth(); int intrinsicHeight = drawable.getIntrinsicHeight(); float R = Math.min(intrinsicWidth, intrinsicHeight) / 2; Bitmap bmp = transformBitmap(drawable, intrinsicWidth, intrinsicHeight, R); Matrix imageMatrix = getImageMatrix(); if((imageMatrix==null || imageMatrix.isIdentity()) && getPaddingTop()==0 && getPaddingLeft()==0){ drawCircleImage(canvas, bmp); }else { if (imageMatrix != null && !imageMatrix.isIdentity()) { canvas.concat(imageMatrix); } final int saveCount = canvas.getSaveCount(); canvas.save(); if (getCropToPadding()) { final int scrollX = getScrollX(); final int scrollY = getScrollY(); canvas.clipRect(scrollX + getPaddingLeft(), scrollY + getPaddingTop(), scrollX + getRight() - getLeft() - getPaddingRight(), scrollY + getBottom() - getTop() - getPaddingBottom()); } canvas.translate(getPaddingLeft(), getPaddingTop()); drawCircleImage(canvas, bmp); canvas.restoreToCount(saveCount); } if(bmp!=null && !bmp.isRecycled()) { bmp.recycle(); } }else{ super.onDraw(canvas); } } private void drawCircleImage(Canvas canvas, Bitmap bmp) { try { DrawFilter drawFilter = canvas.getDrawFilter(); canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG)); canvas.drawBitmap(bmp, 0, 0, null); canvas.setDrawFilter(drawFilter); }catch (Exception e){ e.printStackTrace(); return; } } @NonNull private Bitmap transformBitmap(Drawable drawable, int intrinsicWidth, int intrinsicHeight, float r) { Bitmap bmp = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888); Canvas targetCanvas = new Canvas(bmp); try { drawable.draw(targetCanvas); for (int y = 0; y < intrinsicHeight; y++) { for (int x = 0; x < intrinsicWidth; x++) { if ((Math.pow(x - intrinsicWidth / 2, 2) + Math.pow(y - intrinsicHeight / 2, 2)) <= Math.pow(r, 2)) { continue; } bmp.setPixel(x, y, Color.TRANSPARENT); } } }catch (Exception e){ NCFLog.e("transformBitmap","e="+e.getLocalizedMessage()); e.printStackTrace(); } return bmp; } public boolean isHardware(Bitmap sourceBitmap){ if(sourceBitmap==null) return false; if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) { return sourceBitmap.getConfig() == Bitmap.Config.HARDWARE; } return false; } }

 

 

 

原文链接:https://my.oschina.net/ososchina/blog/3036297
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章