gpt4 book ai didi

ios - 如何将 HSB 滤色器应用到 UIImage

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:36:01 26 4
gpt4 key购买 nike

为了一个关于 UIImage 着色的项目,我折腾了几天。这个想法是,该应用程序将启动一组图像,我必须使用从网络服务检索到的值对其进行着色。如果您愿意,可以选择某种主题。

与我合作的设计师给了我一张关于他所有 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)

color converter

因此 HSL 152、100、62 给出 HSB 152、76、100。该方法返回 75 的饱和度和 100 的亮度,所以我们很好。

接下来我需要将这些值应用于图像,所以这里是要更改的代码...

色调:

#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);
}

饱和度:

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

}];

}];

}];

最后一个完成 block 简单地将输出图像应用到 ImageView 。现在这里是结果:

基础图片

base image

着色(仅色调)

hue only

着色(色调和饱和度)

hue and saturation

着色(色调、饱和度和亮度)

hue, saturation and brightness

预期结果

expected result

如您所见,最终图像是全白的(亮度为 100%)。

我完全迷失在这里,我尝试了很多组合(在每个顺序中应用 H、S 和 B),我尝试了其他库,例如 iOS-Image-Filters , 没有任何成功。我还在 Stack Overflow 上阅读了很多问题。

链接:

有人成功地将 HSL/HSB 值应用于 UIImages 吗?

最佳答案

最后,我们决定改变技术。我现在使用半透明图像来应用具有所需颜色的混合模式。

正在关注 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;
}

关于ios - 如何将 HSB 滤色器应用到 UIImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22168297/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com