在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?


请注意,从2021年起,只需使用ShapeableImageView


当前回答

以下是我的解决方案:

<com.myproject.ui.RadiusCornerImageView
        android:id="@+id/imageViewPhoto"
        android:layout_width="160dp"
        android:layout_height="160dp"
        app:corner_radius_dp="5"
        app:corner_radius_position="top"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

在java代码中:

public class RadiusCornerImageView extends android.support.v7.widget.AppCompatImageView {
    private int cornerRadiusDP = 0; // dp
    private int corner_radius_position;

    public RadiusCornerImageView(Context context) {
        super(context);
    }

    public RadiusCornerImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RadiusCornerImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RadiusCornerImageView, 0, 0);
        try {
            cornerRadiusDP = typeArray.getInt(R.styleable.RadiusCornerImageView_corner_radius_dp, 0);
            corner_radius_position = typeArray.getInteger(R.styleable.RadiusCornerImageView_corner_radius_position, 0);
        } finally {
            typeArray.recycle();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        float radiusPx = AndroidUtil.dpToPx(getContext(), cornerRadiusDP);
        Path clipPath = new Path();
        RectF rect = null;
        if (corner_radius_position == 0) { // all
            // round corners on all 4 angles
            rect = new RectF(0, 0, this.getWidth(), this.getHeight());
        } else if (corner_radius_position == 1) {
            // round corners only on top left and top right
            rect = new RectF(0, 0, this.getWidth(), this.getHeight() + radiusPx);

    } else {
        throw new IllegalArgumentException("Unknown corner_radius_position = " + corner_radius_position);
    }
    clipPath.addRoundRect(rect, radiusPx, radiusPx, Path.Direction.CW);
    canvas.clipPath(clipPath);
    super.onDraw(canvas);
 }
}

其他回答

为什么不在draw()中进行剪辑?

以下是我的解决方案:

用剪切扩展RelativeLayout 将ImageView(或其他视图)放入布局中:

代码:

public class RoundRelativeLayout extends RelativeLayout {

    private final float radius;

    public RoundRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray attrArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundRelativeLayout);
        radius = attrArray.getDimension(
                R.styleable.RoundRelativeLayout_radius, 0);
    }

    private boolean isPathValid;
    private final Path path = new Path();

    private Path getRoundRectPath() {
        if (isPathValid) {
            return path;
        }

        path.reset();

        int width = getWidth();
        int height = getHeight();
        RectF bounds = new RectF(0, 0, width, height);

        path.addRoundRect(bounds, radius, radius, Direction.CCW);
        isPathValid = true;
        return path;
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.clipPath(getRoundRectPath());
        super.dispatchDraw(canvas);
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.clipPath(getRoundRectPath());
        super.draw(canvas);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int oldWidth = getMeasuredWidth();
        int oldHeight = getMeasuredHeight();
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int newWidth = getMeasuredWidth();
        int newHeight = getMeasuredHeight();
        if (newWidth != oldWidth || newHeight != oldHeight) {
            isPathValid = false;
        }
    }

}

使用这个得到圆形图像与边界

    public static Bitmap getCircularBitmapWithBorder(Bitmap bitmap, int bordercolor) {
    if (bitmap == null || bitmap.isRecycled()) {
        return null;
    }
    int borderWidth=(int)(bitmap.getWidth()/40);
    final int width = bitmap.getWidth() + borderWidth;
    final int height = bitmap.getHeight() + borderWidth;

    Bitmap canvasBitmap = Bitmap.createBitmap(width, height,
            Bitmap.Config.ARGB_8888);
    BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP,
            TileMode.CLAMP);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(shader);

    Canvas canvas = new Canvas(canvasBitmap);
    float radius = width > height ? ((float) height) / 2f
            : ((float) width) / 2f;
    canvas.drawCircle(width / 2, height / 2, radius, paint);
    paint.setShader(null);
    paint.setStyle(Paint.Style.STROKE);
    paint.setColor(bordercolor);
    paint.setStrokeWidth(borderWidth);
    canvas.drawCircle(width / 2, height / 2, radius - borderWidth / 2,
            paint);
    return canvasBitmap;
}

你可以很容易地使用roundedImageView库:

compile 'com.makeramen:roundedimageview:2.3.0'

然后:

<com.makeramen.roundedimageview.RoundedImageView
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@+id/img_episode"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:elevation="7dp"
  app:riv_border_color="@color/colorPrimary"
  app:riv_border_width="1dip"
  app:riv_corner_radius="10dip"
  app:riv_mutate_background="true"
  />

我知道这个问题已经过时了,但这里有另一种更简单的四舍五入图像的方法:

这是一种编程方法。

创造你的空白……

} public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output); final int color = 0xff424242;
final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels; paint.setAntiAlias(true); 
canvas.drawARGB(0, 0, 0, 0); paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint); return output;

加载图像,然后设置圆角

imageview1.setImageResource(R.drawable.yourimage);

Bitmap bm = ((android.graphics.drawable.BitmapDrawable) imageview1.getDrawable()).getBitmap();
imageview1.setImageBitmap(getRoundedCornerBitmap(bm, 30)); 

以30为半径,你会得到这样的结果:

不管我的图像看起来如何,它只是一个放大的小图标

罗曼盖伊就在那里。

缩小版如下。

Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.image)).getBitmap();

Bitmap bitmapRounded = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(bitmapRounded);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawRoundRect((new RectF(0.0f, 0.0f, bitmap.getWidth(), bitmap.getHeight())), 10, 10, paint);

imageView.setImageBitmap(bitmapRounded);