android - 如何在不创建新位图的情况下创建带有中心裁剪的部分圆角矩形可绘制对象?

标签 android bitmap drawable rounded-corners

背景

我已经了解了如何从位图中创建一个圆形的可绘制对象,以及如何在其周围添加轮廓(也称为描边),here .

问题

我无法找到如何在不创建新位图的情况下仅对位图的某些角进行四舍五入的类似任务,而无需创建新的位图,并且仍然为中心裁剪 ImageView 执行此操作。

我发现了什么

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

/**
 * 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;
}

而且,这是我发现的用于创建作用于所有角落的圆角可绘制对象:

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

但只有当 imageView 显示内容时保持与位图相同的纵横比,并且其大小也已预先确定,此解决方案才有效。

问题

如何创建一个居中裁剪的可绘制对象,显示位图,为特定角设置圆角,并且还能够在其周围显示轮廓/描边?

我想在不创建新位图或扩展 ImageView 的情况下执行此操作。仅使用将位图作为输入的可绘制对象。

最佳答案

SMART 方法是使用 PorterDuff混合模式。创建任何奇特的阴影、混合、“裁剪”效果非常简单和巧妙。你可以找到很多关于 PorterDuff 的好教程。这里是good one .

关于android - 如何在不创建新位图的情况下创建带有中心裁剪的部分圆角矩形可绘制对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36370964/

相关文章:

bitmap - 使用 DirectShow 将电影文件转换为位图文件

java - Android 处理 GIF 文件

android - 将背景可绘制对象设置为 LinearLayout 会导致 OutOfMemoryError

Android:canvas.drawBitmap 和 BitmapDrawable.draw 之间的区别?

android - CollapsingToolbarLayout - 设置 expandedTitleTextAppearance 和 collapsedTitleTextAppearance 可能会导致问题

android - 如何使用 View 的中心作为 RelativeLayout 内的引用点

java - 如何制作每 15 秒运行一次任务的警报管理器

android - 当应用程序在后台时,ViewPager fragment 被破坏?

c - 如何在 C 和 SDL 中拉伸(stretch)位图?

java - 基于图 block 的 map 滚动