我正在尝试使用CGContextSetBlendMode实现html5 canvas globalCompositeOperation并将html5画布运算符(source-in,source-atop等)转换为其对应的CGBlendMode(kCGBlendModeSourceIn,kCGBlendModeSourceAtop等)。
根据规格,这是预期的结果:
[使用CGContextSetBlendMode,我得到了这个:
某些结果是错误的。例如,source-out(在Quartz 2D中为kCGBlendModeSourceOut)不会剪切蓝色矩形。
我不确定哪种实现是正确的。但是我的问题是,是否有解决方法?经过一番修补,我想出了这个解决方案,可以在应用操作之前对目标进行预处理:
这是预处理步骤(假设源路径已设置):
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);
有了解决方法,我几乎得到了我想要的:
除了源输出中的工件外,在圆圈轮廓中带有一些(抗锯齿?)条纹。
有更好的方法吗?我做错了吗?我想念什么吗?
非常感谢,请原谅这个冗长的问题。
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])
其中n
和m
-图像宽度和高度分别以像素为单位。
请注意,遍历像素可能是一项昂贵的操作,尤其是在处理高分辨率图像时。
关于source-out
-它是Porter / Duff合成运算符之一,在某种程度上类似于混合模式。除了两种颜色外,还需要这些颜色的Alpha通道值。 Alpha值表示最终结果中应表示每个源的数量,取决于您要使用的运算符,使用或放弃此“参与”值。
function sourceOut(aColor, bColor, aAlpha, bAlpha) { return bAlpha * (1 - aAlpha) * bColor; }
参考:
Alpha compositingW3C Compositing and Blending Level 1 - 9. Advanced compositing features
Søren Sandmann Pedersen - Porter/Duff Compositing and Blend Modes