Режим смешивания kCGBlendModeMultiply не правильно умножает изображение с цветом

Цель: подкрасить изображение, умножив его на цвет.

Допущения: согласно документации Apple, режим наложения kCGBlendModeMultiply "Умножает выборки исходного изображения на образцы фонового изображения." Что я понимаю из этого: R = S * D для R, G, B и A. Таким образом, если один из 2 пикселей в умножении имеет КРАСНОЕ значение 0,0, КРАСНОЕ в результирующем пикселе будет 0,0.

Результаты: это не происходит, когда цвет имеет альфа. Если я использую черный цвет с альфа-значением 0,5, я ожидаю, что результат будет черным с альфа-значением 0,5 для всех пикселей, где изображение имеет альфа-значение 1,0.

Примечание. Кажется, что все в порядке, когда цветовой альфа равен 1,0. Если я использую черный с альфа-значением 1,0, полученное изображение будет сплошным черным, но здесь я не об этом спрашиваю.

Ожидаемые результаты:

  1. Альфа-изображение должно быть 0,5, потому что это альфа цвета, но вы не видите никакого красного цвета фона, просвечивающего изображение, кроме углов, потому что я использую изображение в качестве обтравочной маски.
  2. Изображение должно быть полностью серым, потому что цвет имеет значения 0,0 для R, G и B. При умножении на 0 результат должен быть 0.

Приведенный ниже код является копией / прошлым того, что я сделал на детской площадке, и на прилагаемом изображении показано исходное изображение, цвет оттенка, результирующее изображение в виде изображения и изображение с красным фоном (для проверки прозрачности) в этот порядок.

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

2 ответа

Решение

Я думаю, что ваши ожидания относительно режима смешанного смешивания и получающегося в результате альфа-компонента просто неверны. Я не ожидал бы, что наложение на непрозрачное изображение сделает его прозрачным.

Документы по режиму наложения указывают на спецификацию PDF для поведения режимов, отличных от Портера-Даффа. Он довольно плотный, но мне кажется, что результат альфа вообще не зависит от режима наложения. И если фон непрозрачен, результат непрозрачен.

Раздел 7.2.7 спецификации содержит сводную информацию о композитных вычислениях. Для наших целей нас не волнует "форма", поэтому все переменные are равны 1.0, а альфа равна непрозрачности (α =). В спецификации сказано, что α = α+ α- (α× α). В вашем случае фон альфа (α) равен 1,0, поэтому:

α = α+ α- (α× α)
α = 1,0+α- (1,0 × α)
α = 1,0+α
α = 1,0

Похоже, что это сообщение блога показывает способ подкрасить изображение: https://robots.thoughtbot.com/designing-for-ios-blending-modes

Другие вопросы по тегам