16

我正在为 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) 时色轮的外观:

我的 inputBrightness = 0 图像

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

我的 inputBrightness = -0.4 图像

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

首先,任何人都可以解释为什么图像看起来像这样吗?我不是色彩专家。奇怪的是,圆的中心很快就变成了黑色,而它的边缘并没有变暗很多。

二、怎样才能达到我想要的效果?

这是我实际希望图像看起来的方式:

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

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

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

4

3 回答 3

10

kCIInputBrightnessKey我还发现of的非线性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. 无论它是否比您的例行程序更快,您都会对其进行基准测试。

于 2013-10-12T19:11:39.510 回答
2

您的 CIColorControls 过滤器按设计工作。它只是将其亮度参数添加到每个像素的红色、绿色和蓝色值。如果负亮度使像素低于 0,则它将剪辑为黑色。如果正亮度将其推至 1 以上,则会剪辑为白色。(其实每个频道都是单独剪辑的……)

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

有用的参考

于 2014-05-19T19:53:45.970 回答
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];
}
于 2013-04-02T07:14:25.163 回答