混合模式(一)

博客介绍了Android中混合模式,它可将两张图片融合,通过Paint类的setXfermode函数实现。介绍了AvoidXfermode、PorterDuffXfermode等子类,提及使用注意点如禁用硬件加速等,还阐述了颜色叠加相关模式,最后总结了模式特点及常见混合情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

混合模式
  • 混合模式能够将两个图片无缝结合,实现两张图片融合的效果,它是通过Paint类中的Xfermode setXfermode(Xfermode xfermode)函数实现的,Xfermode是一个空类和之前一样都是通过自类来实现不同的功能,子类有AvoidXfermode, PixelXorXfermode和PorterDuffXfermode
  • 由于PixelXorXfermode在API16已经完全过时,所以基本用不上
  • AvoidXfermode完全不支持硬件加速和PorterDuffXfermode部分不支持硬件加速
使用注意点:
  • 禁用硬件加速:
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
  • 使用离屏绘制:
//新建图层
int layerId = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
//核心绘制代码
...
//还原图层
canvas.restoreToCount(layerId);
AvoidXfermode(现已不用)
  • 虽然在API16已经禁用,但是还没又可以替代的方法,所以还是可以在API16以上的平台使用
//opColor:一个十六进制的AARRGGBB形式的颜色值
//tolerance:表示容差
//mode:取值为Mode.TARGET(表示将指定的颜色替换掉)和Mode.AVOID(表示将Mode.TARGET的相反区域颜色替换掉)
public AvoidXfermode(int opColor, int tolerance, Mode mode);
  • 容差概念:

    • 容差是指与目标色可以容忍的最大颜色差异,容差越大,所覆盖的颜色区域就越大,当容差为0的时候,表示只选择与目标色一模一样的颜色区域,当容差为100的时候,表示与目标色的颜色差异在100的范围内都是可以接受的,最大的容差为255,在255范围内意味着所有颜色都将被选中。
  • AvoidXfermode原理:

    • 将目标区域的颜色值清空,然后再替换为目标颜色
PorterDuffXfermode:
//mode:表示混合模式,枚举值有18个,表示各种混合模式,每种模式对应一种算法
public PorterXfermode(PorterDuff.Mode mode);
Enum Values算法
ADDSaturate(S + D)
CLEAR[0, 0]
DARKEN[Sa + Da - Sa * Da, Sc * (1-Da) + Dc * (1-Sa) + min(Sc, Dc)]
DST[Da, Dc]
DST_ATOP[Sa, Sa* Dc+ Sc * (1-Da)]
DST_IN[Sa * Da, Sa * Dc]
DST_OUT[Da * (1-Sa), Dc*(1-Sa)]
DST_OVER[Sa+(1-Sa)* Da, Rc = Dc + (1-Sa) + max(Sc, Dc)]
LIGHTEN[Sa + Da - Sa* Da, Sc * (1-Da)+Dc*(1-Sa) + max(Sc, Da)]
MULTIPLY[Sa * Da, Sc * Dc]
OVERLAY
SCREEN[Sa + Da - Sa* Da, Sc + Dc - Sc * Dc]
SRC[Sa, Sc]
SRC_ATOP[Da, Sc* Da + (1-Sa)* Dc]
SRC_IN[Sa * Da, Sc* Da]
SRC_OUT[Sa * (1-Da),Sc*(1-Da)]
SRC_OVER[Sa+(1-Sa)* Da, Rc=Sc+(1-Sa)* Dc]
XOR[Sa+Da-2* Sa * Da, Sc*(1-Da) + (1-Sa)* Dc]
  • 公式参数解释:
参数说明
SaSource alpha 表示源图像的Alpha通道
ScSource color 表示源图像的颜色
DaDestination alpha 表示目标图像的Alpha通道
DcDestination color 表示目标图像的颜色
[1,2]1表示计算后的Alpha通道,2代表计算后的颜色值
  • DST, SRC解释:
DST:目标图像
SRC:源图像

eg: SRC_IN模式

public PorterDuffXfermodeView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setLayerType(LAYER_TYPE_SOFTWARE, null);
    dstBmp = makeDst(width, height);
    srcBmp = makeSrc(width, height);
    paint = new Paint();
}
private Bitmap makeDst(int w, int h){
    Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bm);
    Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
    //画一张空白的图片,然后再图片上画一个黄色的圆形,中间有一个圆形的位图,除圆形以外其他都是空白像素
    p.setColor(0xFFFFCC44);
    canvas.drawOval(new RectF(0, 0, w, h), p);
    return bm;
}


private Bitmap makeSrc(int w, int h){
    Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bm);
    Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);


    p.setColor(0xFF66AAFF);
    canvas.drawRect(0, 0, w,h, p);
    return bm;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    int layId = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
    canvas.drawBitmap(dstBmp, 0, 0, paint);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(srcBmp, width/2, height/2, paint);
    paint.setXfermode(null);
    canvas.restoreToCount(layId);
}

在这里插入图片描述
首先我们绘制的黄色圆形时目标图像, 蓝色圆形时源图像,对于模式SRC_IN [Sa * Da, Sc * Da]来说,当目标图像为看空白像素时,计算结果为空白像素(因为Da=0),当目标图像不透明,相交部分显示源图像像素。

  • SRC_IN模式实在相交时利用目标图像的透明度来改变源图像的透明度的饱和度的,当目标图像的透明度为0时,源图像就完全不显示
颜色叠加的相关模式:
  • 针对色彩变换的模式有:
    • Mode.ADD: 饱和度相加
    • Mode.LIGHTEN:变亮
    • Mode.DARKEN:变暗
    • Mode.MULTIPLY:正片叠底
    • Mode.OVERLAY:叠加
    • Mode.SCREEN:滤色

1.饱和度相加:

Mode.ADD
//ADD模式:对src和dst两张土拍你相交区域的饱和度进行相加
Saturate(S + D)

相交部分饱和度发生变化
在这里插入图片描述

2.变亮模式:

Mode.LIGHTEN
//一般用于灯光效果
[Sa + Da - Sa * Da, Sc*(1-Da)+Dc*(1-Sa)+max(Sc,Dc)]

在这里插入图片描述

3.变暗模式:

Mode.DARKEN
[Sa + Da - Sa * Da, Sc*(1-Da)+Dc*(1-Sa)+min(Sc,Dc)]

在这里插入图片描述

4.正片叠底:

Mode.MULTIPLY
[Sa * Da, Sc * Dc]

在这里插入图片描述

5.叠加模式:

Mode.OVERLAY
Google并未给出相应的算法

在这里插入图片描述

6.滤色模式:

Mode.SCREEN
[Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]

在这里插入图片描述

总结:
  • 这几种模式都是PS中存在的模式,通过计算改版相交区域的颜色值的
  • 除了Mode.MULTIPLY会在目标图像透明时将结果对应区域配置为透明,其他图像都不收目标图像的透明像素的影响,即非相交区域保持原样
  • 一般只考虑两种混合模式:
    • 两个不透明区域的混合
    • 源图像与完全透明区域的混合
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wjxbless

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值