Quartz 2D实现html5 canvas globalCompositeOperation

问题描述 投票:1回答:1

我正在尝试使用CGContextSetBlendMode实现html5 canvas globalCompositeOperation并将html5画布运算符(source-in,source-atop等)转换为其对应的CGBlendMode(kCGBlendModeSourceIn,kCGBlendModeSourceAtop等)。

根据规格,这是预期的结果:

globalCompositeOperation

[使用CGContextSetBlendMode,我得到了这个:

enter image description here

某些结果是错误的。例如,source-out(在Quartz 2D中为kCGBlendModeSourceOut)不会剪切蓝色矩形。

我不确定哪种实现是正确的。但是我的问题是,是否有解决方法?经过一番修补,我想出了这个解决方案,可以在应用操作之前对目标进行预处理:

  1. 剪切源以外的所有内容(即红色圆圈)
  2. 删除目的地(仅将图像保留在圆圈中)

这是预处理步骤(假设源路径已设置):

auto save = CGContextCopyPath(ctx);
CGContextSaveGState(ctx);
CGContextAddRect(ctx, CGRectInfinite);
CGContextEOClip(ctx);
CGContextSetBlendMode(ctx, kCGBlendModeClear);
CGContextAddRect(ctx, CGRectInfinite);
CGContextFillPath(ctx);
CGContextRestoreGState(ctx);
CGContextAddPath(ctx, save);
CGPathRelease(save);

有了解决方法,我几乎得到了我想要的:

enter image description here

除了源输出中的工件外,在圆圈轮廓中带有一些(抗锯齿?)条纹。

有更好的方法吗?我做错了吗?我想念什么吗?

非常感谢,请原谅这个冗长的问题。

html5-canvas quartz-2d
1个回答
0
投票
c[1][1] = f(a[1][1], b[1][1]) c[1][2] = f(a[1][2], b[1][2]) ... c[n][m] = f(a[n][m], b[n][m])

其中nm-图像宽度和高度分别以像素为单位。

请注意,遍历像素可能是一项昂贵的操作,尤其是在处理高分辨率图像时。

关于source-out-它是Porter / Duff合成运算符之一,在某种程度上类似于混合模式。除了两种颜色外,还需要这些颜色的Alpha通道值。 Alpha值表示最终结果中应表示每个源的数量,取决于您要使用的运算符,使用或放弃此“参与”值。

function sourceOut(aColor, bColor, aAlpha, bAlpha) {
  return bAlpha * (1 - aAlpha) * bColor;
}

See JSBin with full example

参考:

Alpha compositing

W3C Compositing and Blending Level 1 - 9. Advanced compositing features

Søren Sandmann Pedersen - Porter/Duff Compositing and Blend Modes

© www.soinside.com 2019 - 2024. All rights reserved.