Android 实现圆角/圆形图片的几种方式

1、Xfermode
绘制两层,先绘制形状,再绘制图片,然后根据Xfermode来去计算两个图层的关系(SRC_IN:显示的区域是二者交集)。
Glide实现圆形图片

static {
    CIRCLE_CROP_BITMAP_PAINT = new Paint(CIRCLE_CROP_PAINT_FLAGS);
    CIRCLE_CROP_BITMAP_PAINT.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
  }
  
/**
   * Crop the image to a circle and resize to the specified width/height.  The circle crop will
   * have the same width and height equal to the min-edge of the result image.
   *
   * @param pool   The BitmapPool obtain a bitmap from.
   * @param inBitmap   The Bitmap to resize.
   * @param destWidth    The width in pixels of the final Bitmap.
   * @param destHeight   The height in pixels of the final Bitmap.
   * @return The resized Bitmap (will be recycled if recycled is not null).
   */
  public static Bitmap circleCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitmap,
      int destWidth, int destHeight) {
    int destMinEdge = Math.min(destWidth, destHeight);
    float radius = destMinEdge / 2f;

    int srcWidth = inBitmap.getWidth();
    int srcHeight = inBitmap.getHeight();

    float scaleX = destMinEdge / (float) srcWidth;
    float scaleY = destMinEdge / (float) srcHeight;
    float maxScale = Math.max(scaleX, scaleY);

    float scaledWidth = maxScale * srcWidth;
    float scaledHeight = maxScale * srcHeight;
    float left = (destMinEdge - scaledWidth) / 2f;
    float top = (destMinEdge - scaledHeight) / 2f;

    RectF destRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);

    // Alpha is required for this transformation.
    Bitmap toTransform = getAlphaSafeBitmap(pool, inBitmap);

    Bitmap result = pool.get(destMinEdge, destMinEdge, Bitmap.Config.ARGB_8888);
    result.setHasAlpha(true);

    BITMAP_DRAWABLE_LOCK.lock();
    try {
      Canvas canvas = new Canvas(result);
      // Draw a circle
      canvas.drawCircle(radius, radius, radius, CIRCLE_CROP_SHAPE_PAINT);
      // Draw the bitmap in the circle
      canvas.drawBitmap(toTransform, null, destRect, CIRCLE_CROP_BITMAP_PAINT);
      clear(canvas);
    } finally {
      BITMAP_DRAWABLE_LOCK.unlock();
    }

    if (!toTransform.equals(inBitmap)) {
      pool.put(toTransform);
    }

    return result;
  }

2、BitmapShader
将drawable转化为bitmap,然后直接初始化BitmapShader,画笔设置Shader,最后在onDraw里面进行画圆。

/**
   * Creates a bitmap from a source bitmap and rounds the corners.
   *
   * <p>This method does <em>NOT</em> resize the given {@link Bitmap}, it only rounds it's corners.
   * To both resize and round the corners of an image, consider
   * {@link com.bumptech.glide.request.RequestOptions#transforms(Transformation[])} and/or
   * {@link com.bumptech.glide.load.MultiTransformation}.
   *
   * @param inBitmap the source bitmap to use as a basis for the created bitmap.
   * @param roundingRadius the corner radius to be applied (in device-specific pixels).
   * @return a {@link Bitmap} similar to inBitmap but with rounded corners.
   * @throws IllegalArgumentException if roundingRadius, width or height is 0 or less.
   */
   public static Bitmap roundedCorners(
      @NonNull BitmapPool pool, @NonNull Bitmap inBitmap, int roundingRadius) {
    Preconditions.checkArgument(roundingRadius > 0, "roundingRadius must be greater than 0.");

    // Alpha is required for this transformation.
    Bitmap toTransform = getAlphaSafeBitmap(pool, inBitmap);
    Bitmap result =
        pool.get(toTransform.getWidth(), toTransform.getHeight(), Bitmap.Config.ARGB_8888);

    result.setHasAlpha(true);

    BitmapShader shader = new BitmapShader(toTransform, Shader.TileMode.CLAMP,
        Shader.TileMode.CLAMP);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(shader);
    RectF rect = new RectF(0, 0, result.getWidth(), result.getHeight());
    BITMAP_DRAWABLE_LOCK.lock();
    try {
      Canvas canvas = new Canvas(result);
      canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
      canvas.drawRoundRect(rect, roundingRadius, roundingRadius, paint);
      clear(canvas);
    } finally {
      BITMAP_DRAWABLE_LOCK.unlock();
    }

    if (!toTransform.equals(inBitmap)) {
      pool.put(toTransform);
    }

    return result;
  }

3、clipPath
clipPath方法会将绘制的图形裁剪下来,然后再把图片画上去。

	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);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值