Android:着色器在“onDraw(canvas)”和“new Canvas(bitmap)”中的行为不同

2023-12-09

我正在尝试创建反射阴影并发现一个问题。

请在我的自定义视图中找到以下代码:

@Override
protected void onDraw(Canvas canvas) {
    //prepare
    canvas.drawColor(Color.GRAY);
    Bitmap source = BitmapFactory.decodeResource(getResources(), R.drawable.icon);

    //First Column
    canvas.drawBitmap(source, 0, 0, new Paint());

    //2nd Column
    canvas.drawBitmap(source, source.getWidth(), 0, new Paint());

    //Reflection
    Matrix matrix = new Matrix();
    matrix.preScale(1.0f, -1.0f);
    matrix.postTranslate(source.getWidth(), source.getHeight()*2);
    canvas.drawBitmap(source, matrix, new Paint());

    Paint paint2 = new Paint();
    LinearGradient shader = new LinearGradient(
            source.getWidth()*3/2, 
            source.getHeight(),
            source.getWidth()*3/2,
            source.getHeight()*2,
            0x7FFFFFFF, 0x00FFFFFF, TileMode.CLAMP);
    paint2.setShader(shader);
    paint2.setXfermode(new PorterDuffXfermode(
            android.graphics.PorterDuff.Mode.DST_IN));
    canvas.drawRect(
            source.getWidth(), 
            source.getHeight(),
            source.getWidth()*2,
            source.getHeight()*2,
            paint2);

    //3rd Column
    Bitmap bitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight()*2, Config.ARGB_8888);
    Canvas canvas2 = new Canvas(bitmap);
    canvas2.drawBitmap(source, 0, 0,  new Paint());
    matrix = new Matrix();
    matrix.preScale(1.0f, -1.0f);
    matrix.postTranslate(0, source.getHeight()*2);
    canvas2.drawBitmap(source, matrix, new Paint());


    paint2 = new Paint();
    shader = new LinearGradient(
            source.getWidth()*1/2, 
            source.getHeight(),
            source.getWidth()*1/2,
            source.getHeight()*2,
            0x7FFFFFFF, 0x00FFFFFF, TileMode.CLAMP);
    paint2.setShader(shader);
    paint2.setXfermode(new PorterDuffXfermode(
            android.graphics.PorterDuff.Mode.DST_IN));
    canvas2.drawRect(
            0, 
            source.getHeight(),
            source.getWidth(),
            source.getHeight()*2,
            paint2);

    canvas.drawBitmap(bitmap, source.getWidth()*2,0, new Paint());
}

我在画布上做同样的事情(我从onDraw(canvas))和canvas2(使用创建new Canvas(bitmap))

But, both drawing different shader effect as follows: different shader effect

为什么着色器效果不同?


考虑第二列中的黑色矩形:

PorterDuff.MODE.DST_IN 定义为 [Sa*Da, Sa*Dc]。由于目标像素是恒定的不透明灰色 (Da=1),因此结果的 Alpha 通道将设置为线性渐变的 Alpha 通道,范围从 0.5 到 1。

你的问题就在那里......在第二列中,你将窗口画布的像素设置为部分透明。从下面能看到什么?窗口背景,仍然是默认的黑色。

在第三列中,您首先绘制到离屏位图,然后将部分透明的离屏位图绘制到窗口画布。这是有效的,因为传入的像素(来自屏幕外位图)不会完全替换已经存在的像素,而是与目标缓冲区混合(在 PorterDuff 术语中,我认为它相当于 SRC_ATOP)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android:着色器在“onDraw(canvas)”和“new Canvas(bitmap)”中的行为不同 的相关文章

随机推荐