我一直在为UIImage着色项目奋斗几天。 这个想法是应用程序将开始一组图像,我将用从Web服务检索的值着色。如果你愿意,可以使用某种主题。
我工作的设计师给了我一张关于他所有Photoshop值的背景图片。
第一个问题是Photoshop使用HSL而iOS使用HSB。因此,第一个挑战是从Photoshop中翻译值。
Photoshop HSL:-28(范围-180 => +180),100(范围-100 => +100),25(范围-100 => +100)。
幸运的是,我在网上发现了一些代码,here it is。
//adapted from https://gist.github.com/peteroupc/4085710
- (void)convertLightnessToBrightness:(CGFloat)lightness withSaturation:(CGFloat)saturation completion:(void (^)(CGFloat, CGFloat))completion
{
if (!completion)
return; //What's the point of calling this method without a completion block!
CGFloat brightness = 0.0f;
CGFloat saturationOut = 0.0f;
if (lightness > 0.0f)
{
CGFloat lumScale = (1.0f - MAX((lightness - 0.5f), 0.0f) * 2.0f);
lumScale = ((lumScale == 0) ? 0 : (1.0f / lumScale));
CGFloat lumStart = MAX(0.0f, (lumScale - 0.5f));
CGFloat lumDiv = (lumScale - lumStart);
lumDiv = (lumStart + (saturation * lumDiv));
saturationOut = ((lumDiv == 0) ? 0.0f : (saturation / lumDiv));
brightness = (lightness + (1.0f - lightness) * saturation);
}
NSLog(@"saturation: %0.2f - brightness: %0.2f", saturationOut, brightness);
completion(saturationOut, brightness);
}
使用online converter我确认此方法返回了正确的值 我需要改变范围(H:0-> 360,S:0-> 100,L:0-> 100)
因此HSL 152,100,62给出HSB 152,76,100。然后该方法返回75表示饱和度,100表示亮度,所以我们很好。
接下来我需要将这些值应用于图像,所以这里是要更改的代码......
HUE:
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0f * M_PI)
- (void)colorize:(UIImage *)input hue:(CGFloat)hueDegrees completion:(void(^)(UIImage *outputHue))completion
{
if (!completion)
return; //What's the point of calling this method without a completion block!
CGFloat hue = DEGREES_TO_RADIANS(hueDegrees);
NSLog(@"degress: %0.2f | radian: %0.2f", hueDegrees, hue);
CIImage *inputImage = [CIImage imageWithCGImage:input.CGImage];
//---
CIFilter *hueFilter = [CIFilter filterWithName:@"CIHueAdjust" keysAndValues:kCIInputImageKey, inputImage, nil];
[hueFilter setDefaults];
[hueFilter setValue:[NSNumber numberWithFloat:hue] forKey:kCIInputAngleKey];
//---
CIImage *outputImage = [hueFilter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *outputUIImage = [UIImage imageWithCGImage:cgimg];
CGImageRelease(cgimg);
completion(outputUIImage);
}
The SATURATION:
- (void)colorize:(UIImage *)input saturation:(CGFloat)saturation completion:(void(^)(UIImage *outputSaturation))completion
{
if (!completion)
return; //What's the point of calling this method without a completion block!
NSLog(@"saturation: %0.2f", saturation);
CIImage *inputImage = [CIImage imageWithCGImage:input.CGImage];
//---
CIFilter *saturationFilter = [CIFilter filterWithName:@"CIColorControls" keysAndValues:kCIInputImageKey, inputImage, nil];
[saturationFilter setDefaults];
[saturationFilter setValue:[NSNumber numberWithFloat:saturation] forKey:@"inputSaturation"];
//---
CIImage *outputImage = [saturationFilter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *outputUIImage = [UIImage imageWithCGImage:cgimg];
CGImageRelease(cgimg);
completion(outputUIImage);
}
明亮度:
- (void)colorize:(UIImage *)input brightness:(CGFloat)brightness completion:(void(^)(UIImage *outputBrightness))completion
{
if (!completion)
return; //What's the point of calling this method without a completion block!
NSLog(@"brightness: %0.2f", brightness);
CIImage *inputImage = [CIImage imageWithCGImage:input.CGImage];
//---
CIFilter *brightnessFilter = [CIFilter filterWithName:@"CIColorControls" keysAndValues:kCIInputImageKey, inputImage, nil];
[brightnessFilter setDefaults];
[brightnessFilter setValue:[NSNumber numberWithFloat:brightness] forKey:@"inputBrightness"];
//---
CIImage *outputImage = [brightnessFilter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *outputUIImage = [UIImage imageWithCGImage:cgimg];
CGImageRelease(cgimg);
completion(outputUIImage);
}
所有东西放在一起:
CGFloat hue = -28.0f; //152 in 360° range (180 - 28 = 152)
CGFloat saturation = 1.0f; //((100 + 100.0f) / 200.0f)
CGFloat lightness = 0.625f; //((25 + 100.0f) / 200.0f)
[self convertLightnessToBrightness:ligthness withSaturation:saturation completion:^(CGFloat saturationOut, CGFloat brightness) {
//saturarationOut = 0.75f and brigthness = 1.0f
[self colorize:input hue:hue completion:^(UIImage *outputHue) {
[self colorize:outputHue saturation:saturationOut completion:^(UIImage *outputSaturation) {
[self colorize:outputSaturation brightness:brightness completion:completion];
}];
}];
}];
最后一个完成块只是将输出图像应用于图像视图。 现在结果如下:
基本图像
着色(仅限色调)
着色(色调和饱和度)
着色(色调,饱和度和亮度)
预期结果
如您所见,最终图像完全是白色(亮度为100%)。
我完全迷失在这里,我尝试了很多组合(在每个顺序中应用H,S和B),我已经尝试了其他库,例如iOS-Image-Filters,没有任何成功。我也在Stack Overflow上阅读了很多问题。
链接:
是否有人成功将HSL / HSB值应用于UIImages?
答案 0 :(得分:1)
最后,我们决定改变技术。 我现在正在使用半透明图像来应用具有所需颜色的混合模式。
关注this post我在UIImage
上创建了一个类别。
- (UIImage *)tintedBackgroundImageWithColor:(UIColor *)tintColor
{
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
[tintColor setFill];
CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
UIRectFill(bounds);
[self drawInRect:bounds blendMode:kCGBlendModeSourceAtop alpha:1.0f];
UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return tintedImage;
}