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

时间:2023-01-23 19:12:19

Goal: To tint an image by multiplying it with a color.

目的:通过与颜色相乘来着色图像。

Assumptions: According to Apple's documentation, the blend mode kCGBlendModeMultiply "multiplies the source image samples with the background image samples." What I understand from this is: R = S * D for R, G, B and A. So if one of the 2 pixels in the multiplication has a RED value of 0.0, the resulting pixel's RED will be 0.0.

假设:根据苹果公司的文件,混合模式kCGBlendModeMultiply“将源图像样本与背景图像样本相乘”。我的理解是:R = S * D表示R, G, B和a,如果乘法中的两个像素中有一个红值为0,那么得到的像素红值为0。

Results: It is not doing that when the color has an alpha. If I use a color that is black with an alpha of 0.5, I would expect the result to be black with an alpha of 0.5 for all the pixels where the image had an alpha of 1.0.

结果:当颜色有alpha值时,它不会这么做。如果我使用的颜色是黑色的,alpha值为0。5,我希望结果是黑色的,所有像素的alpha值都是0。0。

Note: It seems to work alright when the color alpha is 1.0. If I use black with an alpha of 1.0, the resulting image is a solid black image, but that's not what I'm asking here.

注意:当颜色alpha值为1.0时,它似乎可以正常工作。如果我用黑色加上alpha 1.0,得到的图像就是一个纯黑色的图像,但这不是我想要的。

Expected Results:

预期结果:

  1. The image alpha should be 0.5 because that's the alpha of the color, but you don't see any of the red background color shining through the image, except for the corners because I use the image as a clipping mask.
  2. 图像的alpha值应该是0。5因为这是颜色的alpha值,但是你看不到任何红色背景色在图像中闪烁,除了角落,因为我使用图像作为剪切蒙版。
  3. The image should be completely grey because the color has 0.0 values for R, G and B. When you multiply by 0, the result should be 0.
  4. 图像应该完全是灰色的,因为R、G和b的值为0.0。当你乘以0,结果应该是0。

The code below is a copy/past of what I did in the playground, and the image attached shows the original image, the tint color, the result image in an image view and the image view with a red background (to check transparency) in that order.

下面的代码是我在操场上所做的事情的拷贝/过去,所附的图像显示了原始图像、着色颜色、图像视图中的结果图像以及红色背景(检查透明度)的图像视图。

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();

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

2 个解决方案

#1


1  

I think your expectations regarding the multiply blend mode and the resulting alpha component are simply incorrect. I would not expect that blending onto an opaque image would make it transparent.

我认为你对多重混合模式和结果的期望是不正确的。我不认为在不透明的图像上混合会使它透明。

The blend mode docs refer you to the PDF spec for the behavior of the non-Porter-Duff modes. It's fairly dense, but it looks to me like the result alpha is not subject to the blend mode at all. And if the background is opaque, the result is opaque.

混合模式文档将为您提供关于非波特-达夫模式的行为的PDF规范。它相当密集,但在我看来结果alpha根本不受混合模式的影响。如果背景是不透明的,那么结果就是不透明的。

Section 7.2.7 of the spec has a summary of the compositing computations. For our purposes, we don't care about "shape", so all of the ƒ variables are 1.0 and alpha equals opacity (α = ????). The spec says that α???? = α????????−(α????×α????). In your case, the backdrop alpha (α????) is 1.0, so:

规范的7.2.7节有对合成计算的总结。为我们purposes,don't关心"shape",所以ƒ变量都是1.0和α=不透明度(α=????).规范α????=α????+α????−(α????×α????).说在你case,背景α(α????)是1.0,so:

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

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

#2


0  

Looks like this blog post shows a way to tint an image: https://robots.thoughtbot.com/designing-for-ios-blending-modes

看起来这篇博客文章展示了一种给图像着色的方法:https://robots.thoughtbot.com/designing-for ios-blend- mode

#1


1  

I think your expectations regarding the multiply blend mode and the resulting alpha component are simply incorrect. I would not expect that blending onto an opaque image would make it transparent.

我认为你对多重混合模式和结果的期望是不正确的。我不认为在不透明的图像上混合会使它透明。

The blend mode docs refer you to the PDF spec for the behavior of the non-Porter-Duff modes. It's fairly dense, but it looks to me like the result alpha is not subject to the blend mode at all. And if the background is opaque, the result is opaque.

混合模式文档将为您提供关于非波特-达夫模式的行为的PDF规范。它相当密集,但在我看来结果alpha根本不受混合模式的影响。如果背景是不透明的,那么结果就是不透明的。

Section 7.2.7 of the spec has a summary of the compositing computations. For our purposes, we don't care about "shape", so all of the ƒ variables are 1.0 and alpha equals opacity (α = ????). The spec says that α???? = α????????−(α????×α????). In your case, the backdrop alpha (α????) is 1.0, so:

规范的7.2.7节有对合成计算的总结。为我们purposes,don't关心"shape",所以ƒ变量都是1.0和α=不透明度(α=????).规范α????=α????+α????−(α????×α????).说在你case,背景α(α????)是1.0,so:

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

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

#2


0  

Looks like this blog post shows a way to tint an image: https://robots.thoughtbot.com/designing-for-ios-blending-modes

看起来这篇博客文章展示了一种给图像着色的方法:https://robots.thoughtbot.com/designing-for ios-blend- mode