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

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

问题描述

我正在为iOS创建一个颜色选择器。我想让用户选择亮度(亮度)并让色轮反映这种变化。我正在使用Core Image来修改CIColorControls过滤器的亮度。这里是我的代码:
$ b $ pre code - - (CIImage *)oldPhoto:(CIImage *)img withBrightness :(浮动)强度
{
CIFilter * lighten = [CIFilter filterWithName:@CIColorControls];
[lighten setValue:img forKey:kCIInputImageKey];
[lighten setValue:@((intensity * 2.0) - 1.0)forKey:@inputBrightness];
返回lighten.outputImage;

$ / code>

以下是色轮在强度= 0.5(inputBrightness = 0)时的外观:





问题是当色彩强度< 0.5。例如,下面是强度= 0.3(inputBrightness = -0.4)的样子:



请注意,中间有一个黑色圆圈,图像的其余部分没有也正确地变黑了。这应该是一个HSL色轮,所以我想我实际想要改变的是亮度,而不是亮度。首先,任何人都可以解释为什么图像看起来像这样?我不是色彩方面的专家;看起来奇怪的是,这个圆圈的中心很快就会变成黑色,而它的边缘不会变深。第二,我怎么才能达到我想要的效果?



以下是我真正想要的形象:



具有自定义HSL功能和亮度= 0.3。这在CPU上运行,所以对我的需求来说太慢了。我很乐意发布这个HSL函数的代码,但是我没有包含它,因为它似乎没有立即相关。如果您想查看,请询问。



请让我知道您是否有任何疑问,或者是否有任何疑问。感谢!

解决方案

我还发现 kCIInputBrightnessKey CIColorControls 会很烦人。我使用了一个线性 CIToneCurve

  / **改变` CIImage` 

@param inputImage图像的CIImage使其亮度发生变化。
@ param光度光度的百分比变化,范围从-1.0到1.0。

@returnCIImage的图像亮度发生了变化。如果光度为0.0,则返回原始的`inputImage`。
* /

- (CIImage *)changeLuminosityOfCIImage:(CIImage *)inputImage luminosity:(CGFloat)luminosity
{
if(luminosity == 0)
return inputImage;

NSParameterAssert(光度> = -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 来完成。不管它比你的日常工作快,你都会有基准。

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

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

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):

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:

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!

解决方案

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

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

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

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

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