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


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


当前回答

虽然前两个答案是可行的,但我希望再多描述一点。 比如说,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;
}

其他回答

因为所有的答案对我来说都太复杂了,只是为了圆角,我想到了另一个解决方案,我认为值得分享,只是XML,以防你在图像周围有一些空间:

创建一个带有透明内容的带边框的形状,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners 
        android:radius="30dp" />
    <stroke 
        android:color="#ffffffff"
        android:width="10dp" />
</shape> 

然后在RelativeLayout中,你可以先放置你的图像,然后在相同的位置上面的形状与另一个ImageView。封面形状的大小应与边框宽度相等。注意,要取一个较大的角半径,因为外半径已被定义,但内半径是覆盖你的图像。

希望它也能帮助到别人。

根据CQM请求编辑相关布局示例:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/imageToShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/imgCorners"
        android:layout_alignLeft="@+id/imgCorners"
        android:layout_alignRight="@+id/imgCorners"
        android:layout_alignTop="@+id/imgCorners"
        android:background="#ffffff"
        android:contentDescription="@string/desc"
        android:padding="5dp"
        android:scaleType="centerCrop" />

    <ImageView
        android:id="@+id/imgCorners"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:contentDescription="@string/desc"
        android:src="@drawable/corners_white" />

</RelativeLayout>

我认为最简单的解决方法是这样的:-

步骤1 -创建一个形状绘图文件如下所示

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <solid android:color="@color/white" />

    <corners android:radius="@dimen/dimen_10dp" />

    <stroke
        android:width="1dp"
        android:color="@color/white" />
</shape>

步骤2 -在代码中使用上述绘图。

Drawable drawable = ContextCompat.getDrawable(mActivity, R.drawable.photos_round_shape);
            drawable.mutate().setColorFilter(randomColor, PorterDuff.Mode.SRC_ATOP);
            imageView.setBackground(drawable);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
               imageView.setClipToOutline(true);
            }

Glide.with(mContext)
                .setDefaultRequestOptions(getNoAnimationOptions())
                .load(url)
                .into(imageView);

希望这能有所帮助。

有一个很酷的库可以让你塑造imageviews。

这里有一个例子:

<com.github.siyamed.shapeimageview.mask.PorterShapeImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:siShape="@drawable/shape_rounded_rectangle"
    android:src="@drawable/neo"
    app:siSquare="true"/>

形状定义:

<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
    <corners
        android:topLeftRadius="18dp"
        android:topRightRadius="18dp"
        android:bottomLeftRadius="18dp"
        android:bottomRightRadius="18dp" />
    <solid android:color="@color/black" />
</shape>

结果:

这是相当晚的响应,但对于任何其他人正在寻找这个,您可以执行以下代码手动圆角的图像。

http://www.ruibm.com/?p=184

这不是我的代码,但我用过它,它的工作非常出色。我将它用作ImageHelper类中的一个助手,并对它进行了一点点扩展,以便传入给定图像所需的羽化量。

最终代码如下所示:

package com.company.app.utils;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;

public class ImageHelper {
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), 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(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }
}

这不是确切的答案,但它是一个类似的解决方案。它可能会帮助那些和我有同样遭遇的人。

我的图像是一个应用程序logo,它的背景是透明的,我正在应用XML渐变作为图像背景。我在imageView中添加了必要的padding/margin,然后添加了这个作为我的背景:

<?xml version="1.0" encoding="utf-8"?>
<!-- This file defines the gradient used on the background of the main activity. -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <gradient
                android:type="linear"
                android:startColor="@color/app_color_light_background"
                android:endColor="@color/app_color_disabled"
                android:angle="90" />

            <!-- Round the top corners. -->
            <corners
                android:topLeftRadius="@dimen/radius_small"
                android:topRightRadius="@dimen/radius_small" />
        </shape>
    </item>
</selector>