2014-03-04 4 views
2

저는 UIImage 컬러화 프로젝트에 며칠 동안 고생했습니다. 아이디어는 앱이 웹 서비스에서 검색 한 값으로 색상을 지정해야하는 이미지 세트를 착수한다는 것입니다. 원한다면 어떤 종류의 주제가 있습니다.UIImage에 HSB 컬러 필터를 적용하는 방법

내가 작업 한 디자이너가 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을 사용하여이 방법이 올바른 값을 반환하는지 확인했습니다. ,

color converter 그래서 HSL 152, 100, 62 HSB 152 범 (0-> 100 : L, 0-> 100 : 0-> 360, S H)
는 I의 범위를 변경하기 위해 필요한 76, 100. 그리고이 방법은 채도가 75이고 밝기가 100이기 때문에 우리는 좋다.

다음 I 이미지로 그 값을 적용하는데 필요한, 그래서 여기 ... 변경하는 코드

색상 :

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

     }]; 

    }]; 

}]; 

마지막 완성 블록은 단순히 출력 이미지를 이미지보기에 적용합니다.

Base 이미지

base image

색상 화 (색조 만)

hue only

색상 화 (색조 및 채도)

hue and saturation

: 지금 현재 결과이다 516,

색상 화 (색조, 채도 및 밝기)

hue, saturation and brightness

예상 결과

expected result

하면 알 수있는 바와 같이, 최종 이미지 (brigthness 100 %)이 완전히 흰색으로된다.

나는 완전히 잃어 버렸고, 많은 조합 (모든 순서로 H, S, B를 적용)을 시도했지만, 아무런 성공도없이 iOS-Image-Filters과 같은 다른 라이브러리를 시도했다. 스택 오버플로에 관해서도 많은 질문을 읽었습니다.

링크 : 사람으로

는 UIImages에 HSL/HSB 값을 적용 성공?

답변

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; 
} 
관련 문제