【问题标题】:Android: What is Source and Destination values in Porter Duff ModeAndroid:什么是 Porter Duff 模式下的源值和目标值
【发布时间】:2021-09-30 06:00:33
【问题描述】:

我实现了一个自定义视图。我正在使用 Paint 的 Porter Duff 模式绘制位图,以便在另一个视图中对图像产生不同的效果。我的代码流程如下:

Layout:
<ImageView>
</ImageView>
<CustomView>
Constraint with the image view so that it lies on top in view group.
</CustomView>

Custom View:

onDraw(canvas)
{
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, 0, 0, paint);
}

现在我的问题是,根据documentation of PorterDuff,它主要融合了两个图像。我知道源值是我正在绘制的位图,但我想知道这里的目标是什么? 当我使用 DST 模式时,自定义视图中没有绘制任何内容。 ImageView 目标中的图像在这里吗?但是怎么做?这是两种不同的看法。这些视图如何相互交流?

【问题讨论】:

    标签: android canvas paint porter-duff


    【解决方案1】:

    正如您已经说过的,视图是分开的,不能相互混合。但您可以堆叠任意数量的位图或可绘制对象,然后在某个视图的画布上绘制结果。

    目的地是已经在画布上绘制的内容。您不应该在 ImageView 中创建额外的 CustomImageView。相反,扩展 ImageView 类并覆盖 onDraw 函数。

    请注意,在被覆盖的onDraw 内部,您应该首先在第一行调用super.onDraw(canvas);。通过这样做,您首先绘制为 imageview 定义的图像(即在 xml 中使用 app:srcCompat="...")。现在这张图片成为你的目的地,你可以在之后混合它。

    以下代码创建一个图像视图,在图像中裁剪一个圆圈:

    首先绘制图像,然后 DST_IN 绘制圆圈。

    DST_IN:仅在 SRC 不透明的地方绘制目的地。

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.PorterDuff;
    import android.graphics.PorterDuffXfermode;
    import android.util.AttributeSet;
    
    import androidx.appcompat.widget.AppCompatImageView;
    
    
    public class CircleImageView extends AppCompatImageView {
    
        Paint paint;
        public CircleImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
            setLayerType(View.LAYER_TYPE_HARDWARE,null);
            paint=new Paint();
            paint.setColor(Color.WHITE);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        }
    
    
        protected void onDraw(Canvas canvas){
            super.onDraw(canvas);
            canvas.drawCircle(getWidth()*0.5f,getHeight()*0.5f,getHeight()*0.25f,paint);
        }
    
    }
    

    编辑:

    如果您直接在画布上绘制,请在自定义视图的构造函数中添加以下行:setLayerType(View.LAYER_TYPE_HARDWARE,null);。

    【讨论】:

    • 我没有在图像视图中创建自定义视图。这两个是完全独立的视图组件。自定义视图位于视图组中的图像视图之上。自定义视图有意扩展视图类,而不是图像视图。我的画布是空的。除了源位图,我没有画任何东西。我想知道,在这种情况下,目标值是多少?注意:我在 draw 上调用了 super 方法。我在自定义视图类上有很多其他的东西。我不能在这里写整个班级。所以,我只是写了我认为需要回答这个问题的内容。谢谢
    猜你喜欢
    • 2012-05-02
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 2017-03-02
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多