详解Paint的setXfermode(Xfermode xfermode)

一、setXfermode(Xfermode xfermode)

Xfermode国外有大神称之为过渡模式,这种翻译比较贴切但恐怕不易理解,大家也可以直接称之为图像混合模式,因为所谓的“过渡”其实就是图像混合的一种,这个方法跟我们上面讲到的setColorFilter蛮相似的。查看API文档发现其果然有三个子类:AvoidXfermode, PixelXorXfermode和PorterDuffXfermode,这三个子类实现的功能要比setColorFilter的三个子类复杂得多。

二、AvoidXfermode

2.1 关闭硬件加速

这个API因为不支持硬件加速在API 16已经过时了(大家可以在HardwareAccel查看那些方法不支持硬件加速)如果想在高于API 16的机子上进行测试,必须现在应用或手机设置中关闭硬件加速,在应用中我们可以通过在AndroidManifest.xml文件中设置application节点下的android:hardwareAccelerated属性为false来关闭硬件加速:

    <application
        android:allowBackup="true"
        android:hardwareAccelerated="false"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

注意:如果你在设置中开启了强制硬件加速(强制使用GPU进行绘制),在代码中配置也是没用的。

2.2 构造方法

AvoidXfermode只有一个含参的构造方法:AvoidXfermode(int opColor, int tolerance, AvoidXfermode.Mode mode)

AvoidXfermode有三个参数,第一个opColor表示一个16进制的可以带透明通道的颜色值例如0x12345678;第二个参数tolerance表示容差值,那么什么是容差呢?你可以理解为一个可以标识“精确”或“模糊”的东西,表示当前颜色和opColor的差异程度;最后一个参数表示AvoidXfermode的具体模式,其可选值只有两个:AvoidXfermode.Mode.AVOID或者AvoidXfermode.Mode.TARGET,两者的意思也非常简单,我们先来看

2.3 AvoidXfermode.Mode.TARGET

在该模式下Android会判断画布上的颜色是否会有跟opColor不一样的颜色,opColor可以理解为基准色,仅仅用来做判断。比如我opColor是红色,那么在TARGET模式下就会去判断我们的画布上是否有存在红色(opColor)的地方,如果有,则把该区域“染”上一层我们”画笔的颜色“,否则不“染”色,而tolerance容差值则表示画布上的像素和我们定义的红色之间的差别是多少的时候才去“染”的,比如当前画布有一个像素的色值是(200, 20, 13),而我们的红色值为(255, 0, 0),当tolerance容差值为255时,即便(200, 20, 13)并不等于红色值也会被“染”色,容差值越大“染”色范围越广反之则反。

如果我们想要让图片中白色像素被染上紫色:

   @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // 先画一个图片
        Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.kale);
        canvas.drawBitmap(bitmap, 240, 600, mPaint);

        /*
         * 当画布中有跟0XFFFFFFFF色不一样的地方时候才“染”色
         * 第一个参数颜色是基本色,绘制的时候会判断有没有和基本色相似的颜色(相似程度用容差值表示),有的话就用画笔当前的颜色去绘制那个像素点。
         */
        AvoidXfermode avoidXfermode = new AvoidXfermode(0XFFFFFFFF, 255, AvoidXfermode.Mode.TARGET);

        // “染”什么色是由我们自己决定的
        mPaint.setARGB(255, 211, 53, 243);

        // 设置模式
        mPaint.setXfermode(avoidXfermode);

        // 在图片同等位置上,画一个和位图大小一样的矩形
        canvas.drawRect(240, 600, 240 + bitmap.getWidth(), 600 + bitmap.getHeight(), mPaint);
    }

得到下面的效果:

如果提高容差值,那么接近白色的区域也会被染上紫色。

注意:如果你没关闭硬件加速,那么就会得到像下图这样的一个色块。

2.4 AvoidXfermode.Mode.AVOID

则与TARGET恰恰相反,TARGET是我们指定的颜色是否与画布的颜色一样,而AVOID是我们指定的颜色是否与画布不一样,其他的都与TARGET类似

AvoidXfermode(0XFFFFFFFF, 0, AvoidXfermode.Mode.AVOID):

当模式为AVOID容差值为0时,只有当图片中像素颜色值与0XFFFFFFFF完全不一样的地方才会被染色

AvoidXfermode(0XFFFFFFFF, 255, AvoidXfermode.Mode.AVOID):

当容差值为255时,只要与0XFFFFFFFF稍微有点不一样的地方就会被染色

那么这玩意究竟有什么用呢?比如说当我们只想在白色的区域画点东西或者想把白色区域的地方替换为另一张图片的时候就可以采取这种方式!

三、PixelXorXfermode

与AvoidXfermode一样也在API 16过时了,该类也提供了一个含参的构造方法PixelXorXfermode(int opColor),该类的计算实现很简单,从官方给出的计算公式来看就是:op ^ src ^ dst,像素色值的按位异或运算,如果大家感兴趣,可以自己用一个纯色去尝试,并自己计算异或运算的值是否与得出的颜色值一样,这里我就不讲了,Because it was deprecated and useless。

四、PorterDuffXfermode

Xfermode的最后一个子类也是惟一一个没有过时且沿用至今的子类,这个类是否强大,值得我们好好的学习学习。

时间: 2024-10-07 05:45:54

详解Paint的setXfermode(Xfermode xfermode)的相关文章

详解Paint中的各种set方法

我们用set方法来设置画笔的样式,类似于我们挑选画笔画画的过程. set(Paint src) 顾名思义为当前画笔设置一个画笔,说白了就是把另一个画笔的属性设置Copy给我们的画笔,不累赘了 setAlpha(int a); 设置绘制图形的透明度,设置范围是[0..255] setAntiAlias(boolean aa) 打开抗锯齿.抗锯齿是依赖于算法的,算法决定抗锯齿的效率,在我们绘制棱角分明的图像时,比如一个矩形.一张位图,我们不需要打开抗锯齿. setARGB(int a, int r,

详解Paint的setShader(Shader shader)

一.概述 setShader(Shader shader)中传入的自然是shader对象了,shader类是Android在图形变换中非常重要的一个类.Shader在三维软件中我们称之为着色器,其作用是来给图像着色.它有五个子类,像PathEffect一样,它的每个子类都实现了一种Shader.下面来看看文档中的解释: 子类:BitmapShader, ComposeShader, LinearGradient, RadialGradient, SweepGradient 二.BitmapSha

详解Paint的setPathEffect(PathEffect effect)

一.setPathEffect() 这个方法一看就和path有关,顾名思义,它就是给path设置样式(效果)的.PathEffect这个路径效果类没有具体的实现,效果是由它的六个子类实现的: 这六个子类分别可以实现不同的路径效果: 下面,我们来用代码来具体实现一下. 二.测试代码 2.1 代码框架 首先初始化paint和path,然后配置相关属性,最后作画. package com.kale.cview;public class CustomView extends View { // 实例化画

详解Paint的setMaskFilter(MaskFilter maskfilter)

一.setMaskFilter(MaskFilter maskfilter) setMaskFilter(MaskFilter maskfilter)是paint中的方法,它可以用来对图像进行一定的处理.这个方法需要传入一个MaskFilter对象.但MaskFilter类中没有任何实现方法,所以我们就要认识下它的两个子类BlurMaskFilter和EmbossMaskFilter,前者为模糊遮罩滤镜而后者为浮雕遮罩滤镜. 二.BlurMaskFilter 2.1 初识 我们在之前的cardV

Android中Canvas绘图之Shader使用图文详解

概述 我们在用Android中的Canvas绘制各种图形时,可以通过Paint.setShader(shader)方法为画笔Paint设置shader,这样就可以绘制出多彩的图形.那么Shader是什么呢?做过GPU绘图的同学应该都知道这个词汇,Shader就是着色器的意思.我们可以这样理解,Canvas中的各种drawXXX方法定义了图形的形状,画笔中的Shader则定义了图形的着色.外观,二者结合到一起就决定了最终Canvas绘制的被色彩填充的图形的样子. 类android.graphics

Android基础入门教程——8.3.4 Paint API之—— Xfermode与PorterDuff详解(一)

Android基础入门教程--8.3.4 Paint API之-- Xfermode与PorterDuff详解(一) 标签(空格分隔): Android基础入门教程 本节引言: 不知道标题这两个玩意你熟不熟悉啦,如果自己实现过圆角或者圆形图片,相信对这两个名词 并不模式,一时半伙没想起来?没关系,下面这个图你可曾见过? PS:网上都说在:\samples\android-XX\legacy\ApiDemos\src\com\example\android\apis\graphics 下能找到这个

Android基础入门教程——8.3.7 Paint API之—— Xfermode与PorterDuff详解(四)

Android基础入门教程--8.3.7 Paint API之-- Xfermode与PorterDuff详解(四) 标签(空格分隔): Android基础入门教程 本节引言: 上节我们写了关于Xfermode与PorterDuff使用的第一个例子:圆角&圆形图片ImageView的实现, 我们体会到了PorterDuff.Mode.DST_IN给我们带来的好处,本节我们继续来写例子练练手, 还记得Android基础入门教程--8.3.2 绘图类实战示例给大家带来的拔掉美女衣服的实现吗? 当时我

Android基础入门教程——8.3.6 Paint API之—— Xfermode与PorterDuff详解(三)

Android基础入门教程--8.3.6 Paint API之-- Xfermode与PorterDuff详解(三) 标签(空格分隔): Android基础入门教程 本节引言: 上一节,我们学习了Xfermode中的三儿子:PorterDuffXfermode构造方法中的为一个参数: PorterDuff.Mode,我们在观看了16种图片混排模式后,又自己写代码来验证了一下文档中 18种不同的混排模式,18种是新增了ADD和OVERLAY两种模式!当然,仅仅验证知道是不够的, 本节我们来写个例子

Android基础入门教程——8.3.8 Paint API之—— Xfermode与PorterDuff详解(五)

Android基础入门教程--8.3.8 Paint API之-- Xfermode与PorterDuff详解(五) 标签(空格分隔): Android基础入门教程 本节引言: 好的,上一节中,我们又写了一个关于Xfermode图片混排的例子--擦美女衣服的Demo,加上前面的 利用Xfermode来实现圆角或圆形ImageView,相信大家对Xfermode已经不再像以前那么陌生了,或者 说有点熟悉了,嗯,本节我们来写Xfermode的最后一个例子,通过Xfermode的ProterDuff.