【发布时间】:2016-07-22 02:58:44
【问题描述】:
背景
我已经了解了如何从位图创建圆形可绘制对象,以及如何在其周围添加轮廓(AKA 笔划),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 的情况下执行此操作。仅使用将位图作为输入的可绘制对象。
【问题讨论】:
-
你为什么不合并我的两种方法?请参阅原始线程以获取示例代码(几分钟前制作,因此可能存在一些小错误,但您有一个想法)
-
@pskink 我试过了,但它并不适合我。你的代码(这里:pastebin.com/CsuDbx3w)仍然没有像我写的那样工作,所以我发表了这篇文章。轮廓不允许图像有圆角,即使我使用 setStrokeWidth(0) 时,它不仅显示轮廓,而且不会让图像居中裁剪,并且必须具有恒定大小(使用 wrap_content 和 match_parent 不会让 imageView 显示)
-
“不允许图像有圆角”你可以有 1、2、3 或 4 个圆角,所以我不知道你的意思
-
@pskink 你错过了我写的“大纲”部分。如果没有轮廓,图像会有圆角,但如果有,则不会。即使我添加了 floats 数组,图像看起来也完全是矩形,例如: D roundedCornersDrawable = new D(b, new float[]{20, 20, 0, 0, 40, 40, 0, 0}) 。这里唯一得到圆角的是轮廓本身。当我删除轮廓时,它仍然不能很好地显示,正如我所写的。如果你愿意,我可以给你看一些截图。
标签: android bitmap drawable rounded-corners