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 カラー ホイールのはずなので、実際に変更したいのは明るさではなく輝度だと思います。

まず、画像がこのように見える理由を誰か説明できますか? 私は色の専門家ではありません。円の端があまり暗くならないのに、円の中心がすぐに黒くなるのは奇妙に思えます。

第二に、どうすれば私が望む効果を達成できますか?

これが私が実際に画像をどのように見せたいかです:

CPU 上の HSL 関数で生成された輝度 = 0.3 の画像 (遅すぎる)

これは、カスタム HSL 関数と輝度 = 0.3 で作成されました。これは CPU で実行されるため、私のニーズには遅すぎます。この HSL 関数のコードを投稿できれば幸いですが、すぐには関連性がないように思われたため、含めませんでした。見たい方は直接聞いてください。

ご不明な点やご不明な点がございましたら、お気軽にお問い合わせください。ありがとう!

4

3 に答える 3

10

また、の非線形性が煩わしいこともわかりましkCIInputBrightnessKeyCIColorControls。私は線形を採用しました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 を超えると、白にクリップされます。(実際には、各チャンネルは別々にクリップします...)

もう 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 に答える