Core Image CIColorControls 亮度滤镜会产生错误的效果.如何更改图像的亮度? [英] Core Image CIColorControls brightness filter creates wrong effect. How do I change my image's luminance?

查看:19
本文介绍了Core Image CIColorControls 亮度滤镜会产生错误的效果.如何更改图像的亮度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm creating a color picker for iOS. I would like to enable the user to select the brightness (luminance) and have the color wheel reflect this change. I'm using Core Image to modify the brightness with the CIColorControls filter. Here's my code:

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

Here's how the color wheel looks with intensity = 0.5 (inputBrightness = 0):

问题是当强度

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

The problem is that the color wheel looks wrong when intensity < 0.5. For example, here's how it looks with intensity = 0.3 (inputBrightness = -0.4):

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

Notice that there's a black circle in the middle, and the rest of the image hasn't been darkened correctly either. This is supposed to be an HSL color wheel, so I guess that what I actually want to change is the luminance, not the brightness.

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

First, can anyone explain why the image looks like this? I'm not an expert on color; it seems odd that the center of the circle quickly clips to black while the edges of it don't darken much.

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

Second, how can I achieve the effect I want?

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

Here's how I actually WANT the image to look:

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

This was created with a custom HSL function and luminance = 0.3. This runs on the CPU, so it's far too slow for my needs. I'd be happy to post the code for this HSL function, but I didn't include it because it didn't seem immediately relevant. If you want to see it, just ask.

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

Please let me know if you have any questions, or if anything seems unclear. Thanks!

推荐答案

我还发现CIColorControlskCIInputBrightnessKey的非线性很烦人.我采用了线性 CIToneCurve:

I also found the non-linearity of the kCIInputBrightnessKey of CIColorControls to be annoying. I employed a linear 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%:

Here is your image, reducing the luminosity by 30% using the above routine:

可以使用 CIToneCurve 来完成.无论它是否比您的例行程序更快,您都会对其进行基准测试.

It can be done with CIToneCurve. Whether it's faster than your routine, you'll have benchmark it.

这篇关于Core Image CIColorControls 亮度滤镜会产生错误的效果.如何更改图像的亮度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆