如何将HSB滤色镜应用于UIImage [英] How to apply HSB color filters to UIImage

查看:128
本文介绍了如何将HSB滤色镜应用于UIImage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为UIImage色彩化项目苦苦挣扎了几天. 这个想法是,该应用程序将启动一组图像,这些图像我将不得不使用从Web服务检索的值进行着色.如果您愿意,可以使用某些主题.

I've been struggling for a few days for a project on UIImage colorization. The idea is that the app will embark a set of images that I will have to colorize with values retrieved from a webservice. Some sort of themes if you wish.

与我合作的设计师为我提供了他所有Photoshop值的背景图片.

The designer I work with gave me a background image on all of his Photoshop values.

第一个问题是Photoshop使用HSL,而iOS使用HSB.因此,第一个挑战是转换Photoshop中的值.

The first problem is that Photoshop uses HSL and iOS uses HSB. So the first challenge was to translate the values from Photoshop.

Photoshop HSL:-28(范围-180 => +180),100(范围-100 => +100),25(范围-100 => +100).

Photoshop HSL: -28 (range -180 => +180), 100 (range -100 => +100), 25 (range -100 => +100).

幸运的是,我在网上找到了一些代码,在这里.

Luckily I found some code online, 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);
}

使用在线转换器,我验证了此方法返回的值是正确的.
我需要更改范围(H:0-> 360,S:0-> 100,L:0-> 100)

Using an online converter I verified that this method returns the good values.
I needed to change the ranges (H: 0->360, S: 0->100, L: 0->100)

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

So HSL 152, 100, 62 gives HSB 152, 76, 100. And the method returns 75 for saturation and 100 for brightness so we are good.

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

Next I needed to apply those values to the image, so here is the code to change...

色相:

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

        }];

    }];

}];

最后一个完成块只是将输出图像应用于图像视图. 现在是结果:

The last completion block simply applies the output image to the image view. Now here are the results:

基本图片

着色(仅色相)

着色(色相和饱和度)

着色(色相,饱和度和亮度)

Colorize (hue, saturation and brightness)

预期结果

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

As you can see, the final image is completely white (brigthness is 100%).

我在这里完全迷失了,我尝试了许多组合(在每个顺序中应用H,S和B),我尝试了其他库,例如

I'm completely lost here, I've tried many combination (applying H, S and B in every order), I've tried others libs such as iOS-Image-Filters, without any success. I've also read a lot of question here on Stack Overflow.

链接:

  • Core Image Filter Reference
  • CIHueAdjust core image filter setup
  • How to programmatically change the hue of UIImage?
  • iOS: Values for CIFilter (Hue) from Photoshop

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

As anyone succeeded to apply HSL/HSB value to UIImages?

推荐答案

最后,我们决定更改技术. 现在,我使用半透明图像来应用我想要的颜色的混合模式.

Well finally, we decided to change techniques. I'm now using a semi-transparent image to wich I apply a blend mode with the desired color.

此帖子之后,我在UIImage上做了一个分类.

Following this post I made a category on 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;
}

这篇关于如何将HSB滤色镜应用于UIImage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆