Обновление: Вот Суть для расширения Swift UIColor с использованием приведенного ниже кода.
Если у вас есть изображение в оттенках серого и вы хотите, чтобы белый стал тонирующим цветом , kCGBlendModeMultiply
- это путь. С помощью этого метода вы не сможете получить светлые участки, которые светлее вашего оттенка.
Напротив, если у вас есть изображение не в оттенках серого , ИЛИ у вас есть блики и тени , которые должны быть сохраняется режим смешивания kCGBlendModeColor
. Белый останется белым, а черный останется черным, так как яркость изображения сохранится. Этот режим предназначен только для тонировки - он такой же, как и режим наложения слоя Color
в Photoshop (отказ от ответственности: могут быть немного отличающиеся результаты).
Обратите внимание, что тонировка альфа-пикселей не работает правильно ни в iOS, ни в Photoshop - полупрозрачные черные пиксели не будут оставаться черными. Я обновил ответ ниже, чтобы обойти эту проблему, потребовалось довольно много времени, чтобы выяснить.
Вы также можете использовать один из режимов наложения kCGBlendModeSourceIn/DestinationIn
вместо CGContextClipToMask
.
Если вы хотите создать UIImage
, каждый из следующих разделов кода может быть заключен в следующий код:
UIGraphicsBeginImageContextWithOptions (myIconImage.size, NO, myIconImage.scale); // for correct resolution on retina, thanks @MobileVet
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, myIconImage.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGRect rect = CGRectMake(0, 0, myIconImage.size.width, myIconImage.size.height);
// image drawing code here
UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Итак, вот код для тонирования прозрачного изображения с помощью kCGBlendModeColor
:
// draw black background to preserve color of transparent pixels
CGContextSetBlendMode(context, kCGBlendModeNormal);
[[UIColor blackColor] setFill];
CGContextFillRect(context, rect);
// draw original image
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextDrawImage(context, rect, myIconImage.CGImage);
// tint image (loosing alpha) - the luminosity of the original image is preserved
CGContextSetBlendMode(context, kCGBlendModeColor);
[tintColor setFill];
CGContextFillRect(context, rect);
// mask by alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);
Если ваше изображение не имеет полупрозрачных пикселей, вы также можете сделать это с помощью kCGBlendModeLuminosity
:
// draw tint color
CGContextSetBlendMode(context, kCGBlendModeNormal);
[tintColor setFill];
CGContextFillRect(context, rect);
// replace luminosity of background (ignoring alpha)
CGContextSetBlendMode(context, kCGBlendModeLuminosity);
CGContextDrawImage(context, rect, myIconImage.CGImage);
// mask by alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);
Если вам не нужна яркость, поскольку у вас есть изображение с альфа-каналом, которое должно быть окрашено в цвет, вы можете сделать это более эффективным способом:
// draw tint color
CGContextSetBlendMode(context, kCGBlendModeNormal);
[tintColor setFill];
CGContextFillRect(context, rect);
// mask by alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, rect, myIconImage.CGImage);
или наоборот:
// draw alpha-mask
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextDrawImage(context, rect, myIconImage.CGImage);
// draw tint color, preserving alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
[tintColor setFill];
CGContextFillRect(context, rect);
Веселись!