Ral*_*eon 45
对于更受控制的方法,使用绘制的porter-duff Xfer模式绘制圆角矩形并将其遮罩到图像上.
首先设置Xfer绘图和圆角位图:
Bitmap myCoolBitmap = ... ; // <-- Your bitmap you want rounded
int w = myCoolBitmap.getWidth(), h = myCoolBitmap.getHeight();
// We have to make sure our rounded corners have an alpha channel in most cases
Bitmap rounder = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(rounder);
// We're going to apply this paint eventually using a porter-duff xfer mode.
// This will allow us to only overwrite certain pixels. RED is arbitrary. This
// could be any color that was fully opaque (alpha = 255)
Paint xferPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
xferPaint.setColor(Color.RED);
// We're just reusing xferPaint to paint a normal looking rounded box, the 20.f
// is the amount we're rounding by.
canvas.drawRoundRect(new RectF(0,0,w,h), 20.0f, 20.0f, xferPaint);
// Now we apply the 'magic sauce' to the paint
xferPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
Run Code Online (Sandbox Code Playgroud)
现在将此位图应用于图像的顶部:
Bitmap result = Bitmap.createBitmap(myCoolBitmap.getWidth(), myCoolBitmap.getHeight() ,Bitmap.Config.ARGB_8888);
Canvas resultCanvas = new Canvas(result)
resultCanvas.drawBitmap(myCoolBitmap, 0, 0, null);
resultCanvas.drawBitmap(rounder, 0, 0, xferPaint);
Run Code Online (Sandbox Code Playgroud)
带圆角的位图现在位于结果中.
Jer*_*rry 29
为什么不使用clipPath?
protected void onDraw(Canvas canvas) {
Path clipPath = new Path();
float radius = 10.0f;
float padding = radius / 2;
int w = this.getWidth();
int h = this.getHeight();
clipPath.addRoundRect(new RectF(padding, padding, w - padding, h - padding), radius, radius, Path.Direction.CW);
canvas.clipPath(clipPath);
super.onDraw(canvas);
}
Run Code Online (Sandbox Code Playgroud)
Dhe*_*.S. 17
Romain Guy自己在他的博客中写道:
为了生成圆角图像,我简单地编写了一个自定义Drawable,它使用Canvas.drawRoundRect()绘制一个圆角矩形.诀窍是使用带有BitmapShader的Paint用纹理而不是简单的颜色填充圆角矩形.这是代码的样子:
BitmapShader shader;
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
RectF rect = new RectF(0.0f, 0.0f, width, height);
// rect contains the bounds of the shape
// radius is the radius in pixels of the rounded corners
// paint contains the shader that will texture the shape
canvas.drawRoundRect(rect, radius, radius, paint);
Run Code Online (Sandbox Code Playgroud)
通过将BitmapShader与RadialGradient相结合,示例应用程序更进一步,并伪装了晕影效果.
这是我发现用ImageView做的一种方式.我尝试了其他方法,包括这里的答案和类似的问题,但我发现它们对我来说效果不好,因为我需要将角应用于图像视图而不是直接应用于位图.如果您正在缩放/裁剪/平移该位图,则直接应用于位图将不起作用,因为角也将缩放/裁剪/平移.
public class RoundedCornersImageView extends ImageView {
private final Paint restorePaint = new Paint();
private final Paint maskXferPaint = new Paint();
private final Paint canvasPaint = new Paint();
private final Rect bounds = new Rect();
private final RectF boundsf = new RectF();
public RoundedCornersImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public RoundedCornersImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundedCornersImageView(Context context) {
super(context);
init();
}
private void init() {
canvasPaint.setAntiAlias(true);
canvasPaint.setColor(Color.argb(255, 255, 255, 255));
restorePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
maskXferPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
}
@Override
protected void onDraw(Canvas canvas) {
canvas.getClipBounds(bounds);
boundsf.set(bounds);
canvas.saveLayer(boundsf, restorePaint, Canvas.ALL_SAVE_FLAG);
super.onDraw(canvas);
canvas.saveLayer(boundsf, maskXferPaint, Canvas.ALL_SAVE_FLAG);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawRoundRect(boundsf, 75, 75, canvasPaint);
canvas.restore();
canvas.restore();
}
}
Run Code Online (Sandbox Code Playgroud)
这是使用最终图层合成的硬件层的替代方案:
public class RoundedCornersImageView extends ImageView {
private final Paint restorePaint = new Paint();
private final Paint maskXferPaint = new Paint();
private final Paint canvasPaint = new Paint();
private final Rect bounds = new Rect();
private final RectF boundsf = new RectF();
public RoundedCornersImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public RoundedCornersImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundedCornersImageView(Context context) {
super(context);
init();
}
private void init() {
canvasPaint.setAntiAlias(true);
canvasPaint.setColor(Color.argb(255, 255, 255, 255));
restorePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
maskXferPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
setLayerType(View.LAYER_TYPE_HARDWARE, restorePaint);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.getClipBounds(bounds);
boundsf.set(bounds);
super.onDraw(canvas);
canvas.saveLayer(boundsf, maskXferPaint, Canvas.ALL_SAVE_FLAG);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawRoundRect(boundsf, 75, 75, canvasPaint);
canvas.restore();
}
}
Run Code Online (Sandbox Code Playgroud)
起初我无法使用这种方法,因为我的角落变黑了; 我后来才意识到在阅读这个问题后问题是什么:Android如何在ImageView上应用蒙版?.事实证明,修改画布中的alpha实际上是直接在屏幕上"刮掉",然后向下面的黑色窗口打孔.这就是为什么需要两个层的原因:一个用于应用蒙版,另一个用于将合成图像应用于屏幕.
| 归档时间: |
|
| 查看次数: |
39585 次 |
| 最近记录: |