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


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


当前回答

你可以使用新的ShapableImageView提供的新版本的Android材料库。

为此,您首先需要在应用程序级别构建中添加以下依赖项。gradle文件

implementation 'com.google.android.material:material:<version>'

另外,确保这个应用程序级别的构建。gradle文件有谷歌的Maven资源库谷歌()如下所示

allprojects {
repositories {
  google()
  jcenter()
}

}

在此之后,您可以引用此资源来实现所需类型或形状的imageview。

其他回答

虽然前两个答案是可行的,但我希望再多描述一点。 比如说,ImageView所在的地方有一个活动或片段。您希望绘制图像并按比例缩放。然后你应该在onCreate或onCreateView中写入如下代码:

LinearLayout rootLayout = (LinearLayout) findViewById(R.id.rootLayout);
ImageView image = (ImageView) findViewById(R.id.image);
// Wait till an activity is visible and image can be measured.
rootLayout.post(new Runnable() {
    @Override
    public void run() {
        // Setting ImageView height with aspect ratio.
        Drawable drawable = ContextCompat.getDrawable(getActivity(), R.drawable.your_image);
        int height = getImageViewHeight(drawable, image);

        // Rounding image corners.
        float radius = getResources().getDimension(R.dimen.your_radius_in_dp);
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        Bitmap result = getRoundedBitmap(bitmap, image.getWidth(), height, radius);
        image.setImageBitmap(result);
    }
});

其中设置新的图像高度为:

public static int getImageViewHeight(Drawable drawable, ImageView imageView) {
    imageView.setImageDrawable(drawable);
    int width = drawable.getIntrinsicWidth();
    int height = 0;
    if (width > 0) {
        height = (drawable.getIntrinsicHeight() * imageView.getWidth()) / width;
        imageView.getLayoutParams().height = height;
        imageView.requestLayout();
    }
    return height;
}

然后,您应该编写一个方法来缩放图像并使其圆角。这里的width和height是位图的新维度(更小或更大)。在下面的例子中,我只圆角上的两个角。

private Bitmap getRoundedBitmap(Bitmap bitmap, int width, int height, float radius) {
    // Create scaled bitmap.
    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
    BitmapShader shader = new BitmapShader(scaledBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(shader);

    Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    // First make all corners round.
    canvas.drawRoundRect(new RectF(0, 0, width, height), radius, radius, paint);
    // Then draw bottom rectangle.
    canvas.drawRect(0, height - radius, radius, height, paint);
    canvas.drawRect(width - radius, height - radius, width, height, paint);
    return result;
}

非常感谢第一个回答。下面是修改后的版本,将矩形图像转换为正方形(和圆形),填充颜色作为参数传递。

public static Bitmap getRoundedBitmap(Bitmap bitmap, int pixels, int color) {

    Bitmap inpBitmap = bitmap;
    int width = 0;
    int height = 0;
    width = inpBitmap.getWidth();
    height = inpBitmap.getHeight();

    if (width <= height) {
        height = width;
    } else {
        width = height;
    }

    Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, width, height);
    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(Mode.SRC_IN));
    canvas.drawBitmap(inpBitmap, rect, rect, paint);

    return output;
}

以下是我的解决方案:

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

这里使用ImageLoader

创建DisplayImageOptions:

DisplayImageOptions options = new DisplayImageOptions.Builder()
    // this will make circle, pass the width of image 
    .displayer(new RoundedBitmapDisplayer(getResources().getDimensionPixelSize(R.dimen.image_dimen_menu))) 
    .cacheOnDisc(true)
    .build();

imageLoader.displayImage(url_for_image,ImageView,options);

或者你也可以从Square上使用毕加索图书馆。

Picasso.with(mContext)
    .load(com.app.utility.Constants.BASE_URL+b.image)
    .placeholder(R.drawable.profile)
    .error(R.drawable.profile)
    .transform(new RoundedTransformation(50, 4))
    .resizeDimen(R.dimen.list_detail_image_size, R.dimen.list_detail_image_size)
    .centerCrop()
    .into(v.im_user);

你可以在这里下载RoundedTransformation文件 在这里

相当多的答案!

我遵循了一些人也建议的这个例子:http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

然而,我需要的是一个透明图像后面的彩色圆圈。对于任何有兴趣做同样事情的人…

1)设置FrameLayout的宽度和高度-在我的情况下,图像的大小(50dp)。 2)将带有src = "@drawable/…"的ImageView放在带有图像的ImageView之上。给它一个id,在我的例子中,我叫它iconShape 3) Drawable mask.xml应该是纯色的#ffffffff 4)如果你想在你的代码中动态地改变圆圈的颜色,可以这样做

ImageView iv2 = (ImageView) v.findViewById(R.id.iconShape);
Drawable shape = getResources().getDrawable(R.drawable.mask);
shape.setColorFilter(Color.BLUE, Mode.MULTIPLY);
iv2.setImageDrawable(shape);