使用 alpha 渐变将位图绘制为 Canvas
Drawing a Bitmap to a Canvas with an alpha gradient
我想在 Canvas
上绘制 Bitmap
,并应用(线性)alpha 渐变。重要的一点是我不想用任何其他颜色覆盖图像;背景(来自 View
后面的 View
s,我将把这个 Canvas
画到)应该只是 "shine through"。为了说明,我的目标是这样的(棋盘图案代表后面的 View
)
有人会认为我可以做这样的事情:
Bitmap bitmap = ...;
Paint paint = new Paint();
paint.setShader(new LinearGradient(0, 0, 100, 0, FROM, TO, Shader.TileMode.CLAMP));
canvas.drawBitmap(bitmap, 0, 0, paint);
但是 LinearGradient
的 FROM
和 TO
参数在这里需要是颜色,而不是 alpha 值;所以我看不到具体说明,例如FROM
应该是完全透明的,TO
应该是完全不透明的(不应用任何颜色叠加)。
基于 this answer about masking,我能够使用辅助屏幕外 canvas:
Bitmap backing = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
{
Canvas offscreen = new Canvas(backing);
offscreen.drawBitmap(bitmap, 0, 0, null);
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
paint.setShader(new LinearGradient(0, 0, 100, 0, 0x00000000, 0xFF000000, Shader.TileMode.CLAMP));
offscreen.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
}
canvas.drawBitmap(backing, 0, 0, null);
使用 ComposeShader
,像这样:
class V extends View {
Bitmap bitmap;
Paint paint = new Paint();
public V(Context context) {
super(context);
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.chrome);
Shader shaderA = new LinearGradient(0, 0, bitmap.getWidth(), 0, 0xffffffff, 0x00ffffff, Shader.TileMode.CLAMP);
Shader shaderB = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(new ComposeShader(shaderA, shaderB, PorterDuff.Mode.SRC_IN));
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
}
}
我想在 Canvas
上绘制 Bitmap
,并应用(线性)alpha 渐变。重要的一点是我不想用任何其他颜色覆盖图像;背景(来自 View
后面的 View
s,我将把这个 Canvas
画到)应该只是 "shine through"。为了说明,我的目标是这样的(棋盘图案代表后面的 View
)
有人会认为我可以做这样的事情:
Bitmap bitmap = ...;
Paint paint = new Paint();
paint.setShader(new LinearGradient(0, 0, 100, 0, FROM, TO, Shader.TileMode.CLAMP));
canvas.drawBitmap(bitmap, 0, 0, paint);
但是 LinearGradient
的 FROM
和 TO
参数在这里需要是颜色,而不是 alpha 值;所以我看不到具体说明,例如FROM
应该是完全透明的,TO
应该是完全不透明的(不应用任何颜色叠加)。
基于 this answer about masking,我能够使用辅助屏幕外 canvas:
Bitmap backing = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
{
Canvas offscreen = new Canvas(backing);
offscreen.drawBitmap(bitmap, 0, 0, null);
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
paint.setShader(new LinearGradient(0, 0, 100, 0, 0x00000000, 0xFF000000, Shader.TileMode.CLAMP));
offscreen.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
}
canvas.drawBitmap(backing, 0, 0, null);
使用 ComposeShader
,像这样:
class V extends View {
Bitmap bitmap;
Paint paint = new Paint();
public V(Context context) {
super(context);
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.chrome);
Shader shaderA = new LinearGradient(0, 0, bitmap.getWidth(), 0, 0xffffffff, 0x00ffffff, Shader.TileMode.CLAMP);
Shader shaderB = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(new ComposeShader(shaderA, shaderB, PorterDuff.Mode.SRC_IN));
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
}
}