2012-11-25 71 views
11

我正在爲iOS創建顏色選擇器。我想讓用戶選擇亮度(亮度)並讓色輪反映這種變化。我正在使用Core Image來修改CIColorControls過濾器的亮度。這裏是我的代碼:Core Image CIColorControls亮度過濾器會產生錯誤的效果。我如何改變圖像的亮度?

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

這裏的色輪的外觀與強度= 0.5(inputBrightness = 0):

My image with inputBrightness = 0

的問題是,色輪看上去錯了,當強度< 0.5。例如,這裏是它的外觀與強度= 0.3(inputBrightness = -0.4):

My image with inputBrightness = -0.4

請注意,有一個在中間的黑圈,與圖像的其餘部分沒有正確或者變暗。這應該是一個HSL色輪,所以我想我實際想要改變的是亮度,而不是亮度。

首先,任何人都可以解釋爲什麼圖像看起來像這樣?我不是色彩方面的專家;看起來奇怪的是,這個圓圈的中心很快就會變成黑色,而它的邊緣並沒有變得很暗。

二,如何才能達到我想要的效果?

以下是我真正想要的形象看:

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

這是一個自定義功能HSL和亮度值= 0.3創建的。這在CPU上運行,所以對我的需求來說太慢了。我很樂意發佈這個HSL函數的代碼,但是我沒有包含它,因爲它似乎沒有立即相關。如果你想看到它,請問。

如果您有任何疑問,或者有任何疑問,請讓我知道。謝謝!

+0

一個簡單而快速的可能的方式來解決你的問題是畫在你的彩色圓圈黑色圓圈。您爲這個黑色圓圈選擇的alpha值決定了您的彩色圓圈的亮度。無需重新計算所有顏色。 – mmgp

+0

嘗試在設置CIContext時將工作色彩空間更改爲rgb線性 – ccgus

回答

2

試試這個,使用滑塊變化值: -

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

這並不回答問題。這使用了相同的過濾器「CIColorControls」,他在生成問題中包含的第二個示例時使用了該過濾器。這個答案只能重現問題,並不能解決問題。 – Rob

+1

在我的情況下,我幫助了我很好的工作 –

4

我也發現了CIColorControlskCIInputBrightnessKey的非線性是煩人。我採用的線性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]; 
} 

這裏是您的圖像,使用上述常規減少30%的光度:

reduced

它可與CIToneCurve來完成。不管它比你的日常工作快,你都會有基準。

1

您的CIColorControls過濾器按設計工作。它只是將其亮度參數添加到每個像素的紅色,綠色和藍色值。如果負亮度將像素設置爲0以下,則它會剪裁成黑色。如果正亮度將其推到1以上,則會剪切成白色。 (實際上,每個通道分開...)

另一個問題是CIColorControls在RGB色彩空間中工作。 HSL非常不同。這就是爲什麼您的基準色輪看起來與標準Apple色彩選擇器非常不同。

Useful reference