如何使用中心裁剪创建部分圆角矩形可绘制而不创建新位图?

and*_*per 6 android bitmap rounded-corners drawable

背景

我已经看到了如何创建一个可绘制这是圆了一个位图,以及如何添加一个大纲(AKA中风)周围,这里.

问题

我无法找到如何在不绘制新位图的情况下仅对位图的某些角进行舍入,而不是创建新的位图,并且仍然可以用于中心裁剪ImageView.

我发现了什么

这是我发现的,但它确实创建了一个新的位图,并且在带有center-crop的imageView中使用它时(源于此处):

/**
 * Create rounded corner bitmap from original bitmap.
 *
 * @param input                               Original bitmap.
 * @param cornerRadius                        Corner radius in pixel.
 * @param squareTL,squareTR,squareBL,squareBR where to use square corners instead of rounded ones.
 */
public static Bitmap getRoundedCornerBitmap(final Bitmap input, final float cornerRadius, final int w, final int h,
                                            final boolean squareTL, final boolean squareTR, final boolean squareBL, final boolean squareBR) {
    final Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
    final Canvas canvas = new Canvas(output);
    final int color = 0xff424242;
    final Rect rect = new Rect(0, 0, w, h);
    final RectF rectF = new RectF(rect);
    // make sure that our rounded corner is scaled appropriately
    Paint paint = new Paint();
    paint.setXfermode(null);
    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, paint);
    // draw rectangles over the corners we want to be square
    if (squareTL) 
        canvas.drawRect(0, 0, w / 2, h / 2, paint);
    if (squareTR) 
        canvas.drawRect(w / 2, 0, w, h / 2, paint);
    if (squareBL) 
        canvas.drawRect(0, h / 2, w / 2, h, paint);
    if (squareBR) 
        canvas.drawRect(w / 2, h / 2, w, h, paint);
    paint.setXfermode(PORTER_DUFF_XFERMODE_SRC_IN);
    canvas.drawBitmap(input, 0, 0, paint);
    return output;
}
Run Code Online (Sandbox Code Playgroud)

而且,这是我发现创建一个可以在各个角落起作用的圆角可绘制的东西:

public static class RoundedCornersDrawable extends Drawable {
    private final float mCornerRadius;
    private final RectF mRect = new RectF();
    private final BitmapShader mBitmapShader;
    private final Paint mPaint;

    public RoundedCornersDrawable(final Bitmap bitmap, final float cornerRadius) {
        mCornerRadius = cornerRadius;
        mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,
                Shader.TileMode.CLAMP);
        mPaint = new Paint();
        mPaint.setAntiAlias(false);
        mPaint.setShader(mBitmapShader);
        mRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
    }

    @Override
    protected void onBoundsChange(final Rect bounds) {
        super.onBoundsChange(bounds);
        mRect.set(0, 0, bounds.width(), bounds.height());
    }

    @Override
    public void draw(final Canvas canvas) {
        canvas.drawRoundRect(mRect, mCornerRadius, mCornerRadius, mPaint);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public void setAlpha(final int alpha) {
        mPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(final ColorFilter cf) {
        mPaint.setColorFilter(cf);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果imageView显示内容,同时保持与位图相同的宽高比,并且其大小也是预先确定的,则此解决方案才有效.

这个问题

如何创建一个中心裁剪的drawable,它显示一个位图,具有特定角落的圆角,并且还能够显示它周围的轮廓/笔划?

我想这样做而不创建新的位图或扩展ImageView.仅使用具有位图作为输入的drawable.

Car*_*los 5

SMART方式是使用PorterDuff混合模式.创建任何花哨的阴影,混合,"裁剪"效果都非常简单和光滑.你可以找到很多关于PorterDuff的好教程.这里很好.


Omi*_*nia 2

我总是使用这个库来实现你正在寻找的东西。您可以圆化任何您想要的角并添加描边。

https://github.com/vinc3m1/RoundedImageView

您可以使用它或查看它的源代码以获取灵感。

编辑

无需使用图像视图并自行制作位图或可绘制对象并将其显示在图像视图中。只需将图像视图替换为圆形图像视图,它就会为您处理所有事情,而无需任何额外的代码工作!这是示例:

<com.makeramen.roundedimageview.RoundedImageView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/imageView1"
    android:scaleType="centerCrop"
    app:riv_corner_radius="8dp"
    app:riv_border_width="2dp"
    app:riv_border_color="#333333"
    app:riv_oval="false" />
Run Code Online (Sandbox Code Playgroud)

在代码中,只需将任何图像资源传递给它或使用任何图像加载器即可。

RoundedImageView myRoundedImage=(RoundedImageView)findViewById(R.id.imageView1);
myRoundedImage.setImageResource(R.drawable.MY_DRAWABLE);
// OR
ImageLoader.getInstance().displayImage(YOUR_IMAGE_URL, myRoundedImage);
Run Code Online (Sandbox Code Playgroud)

如果你只想将特定的角变成圆角,请尝试以下操作:

 <com.makeramen.roundedimageview.RoundedImageView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/imageView1"
    android:scaleType="centerCrop"
    app:riv_corner_radius_top_right="8dp"
    app:riv_corner_radius_bottom_right="8dp"
    app:riv_border_width="2dp"
    app:riv_border_color="#333333"
    app:riv_oval="false" />
Run Code Online (Sandbox Code Playgroud)