【问题标题】:Core Image CIColorControls brightness filter creates wrong effect. How do I change my image's luminance?Core Image CIColorControls 亮度滤镜会产生错误的效果。如何更改图像的亮度?
【发布时间】:2012-11-12 21:25:31
【问题描述】:

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

问题是当强度

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

首先,谁能解释一下为什么图片看起来像这样?我不是色彩专家。奇怪的是,圆的中心很快就变黑了,而它的边缘却没有变暗很多。

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

这就是我真正想要的图像外观:

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

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

【问题讨论】:

  • 解决问题的一种简单且可能快速的方法是在彩色圆圈上画一个黑色圆圈。您为这个黑色圆圈选择的 alpha 决定了彩色圆圈的亮度。无需重新计算所有颜色。
  • 在设置 CIContext 时尝试将工作颜色空间更改为 rgb 线性

标签: ios ios5 graphics core-graphics core-image


【解决方案1】:

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

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

【讨论】:

  • 这没有回答问题。这使用了他在生成问题中包含的第二个样本时使用的相同过滤器CIColorControls。这个答案只是重现问题,并没有解决它。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    Useful reference

    【讨论】:

    • 它按预期工作对我来说没有任何意义,因为我找不到不改变原始图像的 CIColorControls 设置。事实上,默认值会极大地改变图像,即使调整它们,我也找不到不影响图像的值。
    • 对于 CIColorControls,0.0 的亮度参数将使图像保持不变。也就是说,它既不会增加也不会减少亮度。同样,饱和度参数 1.0 或对比度参数 1.0 将使图像保持不变。见developer.apple.com/library/archive/documentation/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 2012-04-19
    • 1970-01-01
    相关资源
    最近更新 更多