Core Image CIColorControls亮度滤镜会产生错误的效果。 如何更改图像的亮度?

我正在为iOS创建一个颜色选择器。 我想让用户选择亮度(亮度)并让色轮反映这种变化。 我正在使用Core Image使用CIColorControlsfilter修改亮度。 这是我的代码:

-(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)时的外观:

我的图像inputBrightness = 0

问题是当强度<0.5时,色轮看起来不对劲。 例如,这是它的强度= 0.3(inputBrightness = -0.4):

我的图像是inputBrightness = -0.4

请注意,中间有一个黑色圆圈,图像的其余部分也没有正确变暗。 这应该是一个HSL色轮,所以我想我真正想要改变的是亮度,而不是亮度。

首先,任何人都可以解释为什么图像看起来像这样? 我不是色彩方面的专家; 看起来奇怪的是,圆圈的中心快速剪切成黑色,而它的边缘不会变暗。

其次,我怎样才能达到我想要的效果?

这是我实际上想要看图像的方式:

亮度= 0.3的图像,在CPU上使用HSL功能生成(太慢)

这是使用自定义HSL函数创建的,亮度= 0.3。 这在CPU上运行,因此对我的需求来说太慢了。 我很乐意发布这个HSL函数的代码,但我没有包含它,因为它似乎没有立即相关。 如果你想看到它,请问。

如果您有任何疑问或有任何不清楚的地方,请告诉我。 谢谢!

我还发现kCIInputBrightnessKeyCIColorControls的非线性很烦人。 我采用了线性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%:

减少

它可以用CIToneCurve完成。 无论它比你的日常工作更快,你都会对它进行基准测试。

您的CIColorControlsfilter按设计工作。 它只是将亮度参数添加到每个像素的红色,绿色和蓝色值。 如果负亮度采用低于0的像素,则剪辑为黑色。 如果正亮度将其推过1,则会将其剪切为白色。 (实际上,每个频道分别剪辑……)

另一个问题是CIColorControls在RGB色彩空间中工作。 HSL非常不同。 这就是为什么您的基色轮与标准Apple颜色选择器看起来非常不同。

有用的参考

试试这个并使用滑块更改值: –

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