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

匿名 (未验证) 提交于 2019-12-02 23:52:01

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

3、设置画笔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;     }

4、修改像素

该方法无法支持抗锯齿,并且不支持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://blog.csdn.net/androidokk/article/details/97274222
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!