我正在为iOS创建颜色选择器。我想让用户选择亮度(亮度)并让色轮反映这种变化。我正在使用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)时的外观:
问题是当强度<100时,色轮看起来不对劲。 0.5。例如,这是它在强度= 0.3(inputBrightness = -0.4)时的外观:
请注意,中间有一个黑色圆圈,图像的其余部分也没有正确变暗。这应该是一个HSL色轮,所以我想我真正想要改变的是亮度,而不是亮度。
首先,任何人都可以解释为什么图像看起来像这样?我不是色彩方面的专家;看起来很奇怪,圆圈的中心快速剪成黑色,而它的边缘不会变暗。
其次,我怎样才能达到我想要的效果?
以下是我实际想要看图像的方式:
这是使用自定义HSL函数创建的,亮度= 0.3。这在CPU上运行,因此对我的需求来说太慢了。我很乐意发布这个HSL函数的代码,但我没有包含它,因为它似乎没有立即相关。如果你想看到它,请问。
如果您有任何疑问或有任何疑问,请与我们联系。谢谢!
答案 0 :(得分:6)
我还发现kCIInputBrightnessKey
CIColorControls
的非线性很烦人。我使用了线性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
完成。无论它比你的日常工作更快,你都会有它的基准。
答案 1 :(得分: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];
}
答案 2 :(得分:2)
您的CIColorControls过滤器按设计运行。它只是将亮度参数添加到每个像素的红色,绿色和蓝色值。如果负亮度采用低于0的像素,则会剪切为黑色。如果正亮度将其推过1,则会将其剪切为白色。 (实际上,每个频道分别剪辑......)
另一个问题是CIColorControls在RGB色彩空间中工作。 HSL非常不同。这就是为什么你的基色轮与标准的Apple颜色选择器看起来非常不同。