2012-11-25 4 views
11

Tworzę próbnik kolorów na iOS. Chciałbym umożliwić użytkownikowi wybranie jasności (luminancji) i odzwierciedlenie tej zmiany w kole kolorów. Używam Core Image do modyfikacji jasności przy pomocy filtru CIColorControls. Oto mój kod:Obraz podstawowy Filtr jasności CIColorControls tworzy zły efekt. Jak zmienić luminację obrazu?

-(CIImage *)oldPhoto:(CIImage *)img withBrightness:(float)intensity 
{ 
    CIFilter *lighten = [CIFilter filterWithName:@"CIColorControls"]; 
    [lighten setValue:img forKey:kCIInputImageKey]; 
    [lighten setValue:@((intensity * 2.0) - 1.0) forKey:@"inputBrightness"]; 
    return lighten.outputImage; 
} 

Oto jak wygląda koło kolorów z intensywnością = 0,5 (inputBrightness = 0):

My image with inputBrightness = 0

Problem polega na tym, że koło kolor wygląda źle, gdy intensywność < 0.5. Na przykład, oto jak to wygląda z intensywnością = 0,3 (inputBrightness = -0,4):

My image with inputBrightness = -0.4

Zauważ, że istnieje czarny okrąg w środku, a reszta obrazu nie został zaciemniony poprawnie albo . To ma być koło kolorów HSL, więc domyślam się, że to, co chcę zmienić, to luminancja, a nie jasność.

Po pierwsze, czy ktoś może wyjaśnić, dlaczego obraz wygląda tak? Nie jestem ekspertem od koloru; dziwne wydaje się, że środek koła szybko przycina się na czarno, a jego krawędzie nie są zbyt ciemne.

Po drugie, w jaki sposób mogę uzyskać pożądany efekt?

Oto jak ja faktycznie obraz ma wyglądać:

Image with luminance = 0.3, generated with HSL function on CPU (too slow)

ten został stworzony z funkcją zwyczaj HSL i luminancji = 0,3. To działa na procesorze, więc jest zbyt wolny dla moich potrzeb. Z przyjemnością opublikuję kod dla tej funkcji HSL, ale nie uwzględniłem jej, ponieważ nie wydawało się to natychmiast istotne. Jeśli chcesz to zobaczyć, po prostu zapytaj.

Proszę dać mi znać, jeśli masz jakieś pytania lub jeśli cokolwiek wydaje się być niejasne. Dzięki!

+0

Łatwym i prawdopodobnie szybko sposobem rozwiązania problemu jest narysować czarne kółko nad swoim kolorowym kole. Alfa, którą wybierzesz dla tego czarnego koła, określa luminancję twojego kolorowego koła. Nie ma potrzeby przeliczania wszystkich kolorów. – mmgp

+0

Spróbuj zmienić roboczą przestrzeń kolorów na liniową wartość rgb po skonfigurowaniu CIContext – ccgus

Odpowiedz

2

Spróbuj i zmień wartość za pomocą suwaka: -

- (void)viewDidLoad{ 

    UIImage *aUIImage = showPickedImageView.image; 
    CGImageRef aCGImage = aUIImage.CGImage; 
    aCIImage = [CIImage imageWithCGImage:aCGImage]; 


    context = [[CIContext contextWithOptions:nil] retain]; 
    brightnessFilter = [[CIFilter filterWithName:@"CIColorControls" keysAndValues: @"inputImage", aCIImage, nil] retain]; 

} 

- (IBAction)brightnessSliderValueChanged:(id)sender { 

    [brightnessFilter setValue:[NSNumber numberWithFloat:brightnessSlider.value ] forKey: @"inputBrightness"]; 
    outputImage = [brightnessFilter outputImage]; 
    CGImageRef cgiig = [context createCGImage:outputImage fromRect:[outputImage extent]]; 
    newUIImage = [UIImage imageWithCGImage:cgiig]; 
    CGImageRelease(cgiig); 
    [showPickedImageView setImage:newUIImage]; 
} 
+0

Nie odpowiada to na pytanie. Wykorzystuje ten sam filtr, "CIColorControls", którego użył podczas generowania drugiej próbki zawartej w pytaniu. Ta odpowiedź tylko powiela problem i nie rozwiązuje go. – Rob

+1

w moim przypadku pomogłem mi w dobrej pracy –

4

I także, że nieliniowość na kCIInputBrightnessKey z CIColorControls być denerwujące. Ja stosuje liniową CIToneCurve:

/** Change luminosity of `CIImage` 

@param inputImage The `CIImage` of the image to have it's luminosity changed. 
@param luminosity The percent change of the luminosity, ranging from -1.0 to 1.0. 

@return `CIImage` of image with luminosity changed. If luminosity of 0.0 used, original `inputImage` is returned. 
*/ 

- (CIImage *)changeLuminosityOfCIImage:(CIImage *)inputImage luminosity:(CGFloat)luminosity 
{ 
    if (luminosity == 0) 
     return inputImage; 

    NSParameterAssert(luminosity >= -1.0 && luminosity <= 1.0); 

    CIFilter *toneCurveFilter = [CIFilter filterWithName:@"CIToneCurve"]; 
    [toneCurveFilter setDefaults]; 
    [toneCurveFilter setValue:inputImage forKey:kCIInputImageKey]; 

    if (luminosity > 0) 
    { 
     [toneCurveFilter setValue:[CIVector vectorWithX:0.0 Y:luminosity]       forKey:@"inputPoint0"]; 
     [toneCurveFilter setValue:[CIVector vectorWithX:0.25 Y:luminosity + 0.25 * (1 - luminosity)] forKey:@"inputPoint1"]; 
     [toneCurveFilter setValue:[CIVector vectorWithX:0.50 Y:luminosity + 0.50 * (1 - luminosity)] forKey:@"inputPoint2"]; 
     [toneCurveFilter setValue:[CIVector vectorWithX:0.75 Y:luminosity + 0.75 * (1 - luminosity)] forKey:@"inputPoint3"]; 
     [toneCurveFilter setValue:[CIVector vectorWithX:1.0 Y:1.0]         forKey:@"inputPoint4"]; 
    } 
    else 
    { 
     [toneCurveFilter setValue:[CIVector vectorWithX:0.0 Y:0.0]      forKey:@"inputPoint0"]; 
     [toneCurveFilter setValue:[CIVector vectorWithX:0.25 Y:0.25 * (1 + luminosity)] forKey:@"inputPoint1"]; 
     [toneCurveFilter setValue:[CIVector vectorWithX:0.50 Y:0.50 * (1 + luminosity)] forKey:@"inputPoint2"]; 
     [toneCurveFilter setValue:[CIVector vectorWithX:0.75 Y:0.75 * (1 + luminosity)] forKey:@"inputPoint3"]; 
     [toneCurveFilter setValue:[CIVector vectorWithX:1.0 Y:1 + luminosity]   forKey:@"inputPoint4"]; 
    } 

    return [toneCurveFilter outputImage]; 
} 

Oto obraz, zmniejszając jasność o 30% przy użyciu powyższej procedury:

reduced

można to zrobić z CIToneCurve. Niezależnie od tego, czy jest to szybsze od rutyny, będziesz go porównywać.

1

Twój filtr CIColorControls działa zgodnie z projektem. Po prostu dodaje swój parametr jasności do wartości czerwonego, zielonego i niebieskiego każdego piksela. Jeśli ujemna jasność osiąga piksel poniżej 0, przycina do czarnego. Jeśli dodatnia jasność przesunie ją o 1, zostanie przycięta do białego. (Właściwie każdy kanał klipy osobno ...)

Inną kwestią jest to, że CIColorControls działa w przestrzeni kolorów RGB. HSL jest zupełnie inny.Dlatego Twoje koło kolorów podstawowych wygląda zupełnie inaczej niż standardowy próbnik kolorów Apple.

Useful reference

Powiązane problemy