混合模式 kCGBlendModeMultiply 没有正确地将图像与颜色相乘

Blend mode kCGBlendModeMultiply is not correctly multiplying an image with a color

目标:通过将图像与颜色相乘来为图像着色。

假设:根据Apple的documentation,混合模式kCGBlendModeMultiply "multiplies the source image samples with the background image samples."我由此理解的是:R = S * D 对于 R、G、B 和 A。因此,如果乘法中的 2 个像素之一的 RED 值为 0.0,则生成的像素的 RED 将为 0.0。

结果:当颜色有 alpha 时它不会这样做。如果我使用 alpha 为 0.5 的黑色颜色,对于图像的 alpha 为 1.0 的所有像素,我希望结果为黑色且 alpha 为 0.5。

注意:当颜色alpha为1.0时似乎可以正常工作。如果我使用 alpha 为 1.0 的黑色,则生成的图像是纯黑色图像,但这不是我在这里要问的。

预期结果

  1. 图像 alpha 应为 0.5,因为这是颜色的 alpha,但您看不到任何红色背景颜色透过图像发光,除了角,因为我将图像用作剪贴蒙版。
  2. 图像应该是完全灰色的,因为颜色的 R、G 和 B 值为 0.0。当您乘以 0 时,结果应该是 0。

下面的代码是我在游乐场所做的copy/past,所附图片显示原图色调颜色、图像视图中的结果图像 红色背景的图像视图 (检查透明度)。

import UIKit

// Get the image, its size, blend mode and tint color
var image = UIImage(named: "outlook-checkmark");
var size = image!.size;
var blendMode = kCGBlendModeMultiply;
var tintColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.5);

// Create the graphic context, a frame with the image size
// and get the CGImage.
UIGraphicsBeginImageContextWithOptions(size, false, 0.0);
var context : CGContextRef = UIGraphicsGetCurrentContext();
var aRect = CGRectMake(0, 0, size.width, size.height);
var cgImage = image!.CGImage;

// Converting a UIImage to a CGImage flips the image,
// so apply an upside-down translation
CGContextTranslateCTM(context, 0, size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGContextSetBlendMode(context, blendMode);
CGContextDrawImage(context, aRect, cgImage);

// Set the mask to only tint non-transparent pixels
CGContextClipToMask(context, aRect, cgImage);

CGContextSetFillColorWithColor(context, tintColor.CGColor);
CGContextFillRect(context, aRect);

var returnImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

var imageView = UIImageView(frame: CGRectMake(0, 0, 100, 100));
imageView.image = returnImage;
imageView.backgroundColor = UIColor.redColor();

看起来这个博客 post 展示了一种给图像着色的方法:https://robots.thoughtbot.com/designing-for-ios-blending-modes

我认为您对乘法混合模式和生成的 alpha 分量的期望完全不正确。我不希望混合到不透明图像上会使它变得透明。

混合模式文档让您参考 PDF spec 以了解非 Porter-Duff 模式的行为。它相当密集,但在我看来结果 alpha 根本不受混合模式的影响。如果背景不透明,则结果不透明。

规范的第 7.2.7 节总结了合成计算。出于我们的目的,我们不关心 "shape",因此所有 ƒ 变量均为 1.0 且 alpha 等于不透明度 (α = )。规范说 α = α−(α×α)。在您的例子中,背景 alpha (α) 为 1.0,因此:

α = α−(α×α)
α = 1.0+α−(1.0×α)
α = 1.0+α−α
α = 1.0