Режим смешивания 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, полученное изображение будет сплошным черным, но здесь я не об этом спрашиваю.
Ожидаемые результаты:
- Альфа-изображение должно быть 0,5, потому что это альфа цвета, но вы не видите никакого красного цвета фона, просвечивающего изображение, кроме углов, потому что я использую изображение в качестве обтравочной маски.
- Изображение должно быть полностью серым, потому что цвет имеет значения 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