产生黑白效果的最佳 Core Image 滤镜是啥?

Posted

技术标签:

【中文标题】产生黑白效果的最佳 Core Image 滤镜是啥?【英文标题】:What is the best Core Image filter to produce black and white effects?产生黑白效果的最佳 Core Image 滤镜是什么? 【发布时间】:2012-04-19 07:30:26 【问题描述】:

我正在使用 Core Image,并希望在所选图像上产生黑白效果。

理想情况下,我希望能够访问 Photoshop 上可用的相同类型的选项,即红色、青色、绿色、蓝色和洋红色。目标是创建不同类型的黑白效果。

有谁知道什么过滤器最适合操纵这些选项?如果没有,有人知道使用其他滤镜创建黑白效果的好方法吗?

谢谢

奥利弗

【问题讨论】:

【参考方案1】:
- (UIImage *)imageBlackAndWhite

    CIImage *beginImage = [CIImage imageWithCGImage:self.CGImage];

    CIImage *blackAndWhite = [CIFilter filterWithName:@"CIColorControls" keysAndValues:kCIInputImageKey, beginImage, @"inputBrightness", [NSNumber numberWithFloat:0.0], @"inputContrast", [NSNumber numberWithFloat:1.1], @"inputSaturation", [NSNumber numberWithFloat:0.0], nil].outputImage;
    CIImage *output = [CIFilter filterWithName:@"CIExposureAdjust" keysAndValues:kCIInputImageKey, blackAndWhite, @"inputEV", [NSNumber numberWithFloat:0.7], nil].outputImage; 

    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgiimage = [context createCGImage:output fromRect:output.extent];
    //UIImage *newImage = [UIImage imageWithCGImage:cgiimage];
    UIImage *newImage = [UIImage imageWithCGImage:cgiimage scale:image.scale orientation:image.imageOrientation];
    CGImageRelease(cgiimage);

    return newImage;

更新:对于ios6,有CIColorMonochrome 过滤器,但我玩了它,发现它不如我的。

【讨论】:

如果有人感兴趣。我在这里用过github.com/codler/Battery-Time-Remaining/commit/… @Codler 在阅读了您关于它不适用于 Yosemite 的评论后,我有点认为它也不适用于 iOS 8。但是,我刚刚测试过,发现它在 iOS 8 上仍然可以完美运行 - 甚至可以保留图层透明度。我做到了,但是更新了这一行: UIImage *newImage = [UIImage imageWithCGImage:cgiimage];在我的阅读: UIImage *newImage = [UIImage imageWithCGImage:cgiimage scale:image.scaleorientation:image.imageOrientation];这样我就可以保持比例和方向。【参考方案2】:

这里是 CIColorMonochrome 的示例

- (UIImage *)imageBlackAndWhite

    CIImage *beginImage = [CIImage imageWithCGImage:self.CGImage];

    CIImage *output = [CIFilter filterWithName:@"CIColorMonochrome" keysAndValues:kCIInputImageKey, beginImage, @"inputIntensity", [NSNumber numberWithFloat:1.0], @"inputColor", [[CIColor alloc] initWithColor:[UIColor whiteColor]], nil].outputImage;

    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgiimage = [context createCGImage:output fromRect:output.extent];
    UIImage *newImage = [UIImage imageWithCGImage:cgiimage scale:self.scale orientation:self.imageOrientation];

    CGImageRelease(cgiimage);

    return newImage;

【讨论】:

inputIntensity默认为1,无需手动设置。【参考方案3】:

这是转换为 Swift(iOS 7 及更高版本)的评价最高的解决方案:

func blackAndWhiteImage(image: UIImage) -> UIImage 
    let context = CIContext(options: nil)
    let ciImage = CoreImage.CIImage(image: image)!

    // Set image color to b/w
    let bwFilter = CIFilter(name: "CIColorControls")!
    bwFilter.setValuesForKeysWithDictionary([kCIInputImageKey:ciImage, kCIInputBrightnessKey:NSNumber(float: 0.0), kCIInputContrastKey:NSNumber(float: 1.1), kCIInputSaturationKey:NSNumber(float: 0.0)])
    let bwFilterOutput = (bwFilter.outputImage)!

    // Adjust exposure
    let exposureFilter = CIFilter(name: "CIExposureAdjust")!
    exposureFilter.setValuesForKeysWithDictionary([kCIInputImageKey:bwFilterOutput, kCIInputEVKey:NSNumber(float: 0.7)])
    let exposureFilterOutput = (exposureFilter.outputImage)!

    // Create UIImage from context
    let bwCGIImage = context.createCGImage(exposureFilterOutput, fromRect: ciImage.extent)
    let resultImage = UIImage(CGImage: bwCGIImage, scale: 1.0, orientation: image.imageOrientation)

    return resultImage

【讨论】:

【参考方案4】:

为了创建纯单色效果,我使用了CIColorMatrix,并将 R、G 和 B 向量参数全部设置为 (0.2125, 0.7154, 0.0721, 0),并将 alpha 和偏置向量保留为默认值。

这些值是我在某些时候在互联网上查找的 RGB 到灰度转换系数。通过改变这些系数,您可以改变输入通道的贡献。通过缩放向量的每个副本,并可选择设置偏置向量,您可以对输出进行着色。

【讨论】:

【参考方案5】:

关于建议使用CIColorMonochrome 的答案:现在iOS7(和OS X 10.9)提供了一些专用的灰度滤镜:

CIPhotoEffectTonal

在不显着改变对比度的情况下模仿黑白摄影胶片。

CIPhotoEffectNoir:

用夸张的对比度模仿黑白摄影胶片

来源:https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html

【讨论】:

【参考方案6】:

这是来自@Shmidt 最喜欢的答案,它被写成 UIImage 扩展,并在 Swift 中进行了性能更新:

import CoreImage

extension UIImage

    func imageBlackAndWhite() -> UIImage?
    
        if let beginImage = CoreImage.CIImage(image: self)
        
            let paramsColor: [String : AnyObject] = [kCIInputBrightnessKey: NSNumber(double: 0.0),
                                                     kCIInputContrastKey:   NSNumber(double: 1.1),
                                                     kCIInputSaturationKey: NSNumber(double: 0.0)]
            let blackAndWhite = beginImage.imageByApplyingFilter("CIColorControls", withInputParameters: paramsColor)

            let paramsExposure: [String : AnyObject] = [kCIInputEVKey: NSNumber(double: 0.7)]
            let output = blackAndWhite.imageByApplyingFilter("CIExposureAdjust", withInputParameters: paramsExposure)

            let processedCGImage = CIContext().createCGImage(output, fromRect: output.extent)
            return UIImage(CGImage: processedCGImage, scale: self.scale, orientation: self.imageOrientation)
        
        return nil
    

【讨论】:

【参考方案7】:

macOS (NSImage) Swift 3 版本@FBente 转换@Shmidt 的答案:

extension NSImage

    func imageBlackAndWhite() -> NSImage?
    
        if let cgImage = self.cgImage(forProposedRect: nil, context: nil, hints: nil)
        
            let beginImage = CIImage.init(cgImage: cgImage)
            let paramsColor: [String : AnyObject] = [kCIInputBrightnessKey: NSNumber(value: 0.0),
                                                     kCIInputContrastKey:   NSNumber(value: 1.1),
                                                     kCIInputSaturationKey: NSNumber(value: 0.0)]
            let blackAndWhite = beginImage.applyingFilter("CIColorControls", withInputParameters: paramsColor)

            let paramsExposure: [String : AnyObject] = [kCIInputEVKey: NSNumber(value: 0.7)]
            let output = blackAndWhite.applyingFilter("CIExposureAdjust", withInputParameters: paramsExposure)

            if let processedCGImage = CIContext().createCGImage(output, from: output.extent) 
                return NSImage(cgImage: processedCGImage, size: self.size)
            
        
        return nil
    

【讨论】:

【参考方案8】:

我已经尝试过 Shmidt 解决方案,但在我看来它在 iPad Pro 上暴露得太多了。我只使用了他解决方案的第一部分,没有曝光过滤器:

- (UIImage *)imageBlackAndWhite

    CIImage *beginImage = [CIImage imageWithCGImage:self.CGImage];

    CIImage *blackAndWhite = [CIFilter filterWithName:@"CIColorControls" keysAndValues:kCIInputImageKey, beginImage, @"inputBrightness", [NSNumber numberWithFloat:0.0], @"inputContrast", [NSNumber numberWithFloat:1.1], @"inputSaturation", [NSNumber numberWithFloat:0.0], nil].outputImage;
    CIImage *output = [blackAndWhite valueForKey:@"outputImate"]; 

    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgiimage = [context createCGImage:output fromRect:output.extent];
    //UIImage *newImage = [UIImage imageWithCGImage:cgiimage];
    UIImage *newImage = [UIImage imageWithCGImage:cgiimage scale:image.scale orientation:image.imageOrientation];
    CGImageRelease(cgiimage);

    return newImage;

【讨论】:

以上是关于产生黑白效果的最佳 Core Image 滤镜是啥?的主要内容,如果未能解决你的问题,请参考以下文章

iOS学习笔记9-Core Image

css3滤镜属性filter实现网页变黑白效果

css3滤镜属性filter实现网页变黑白效果

如何在位图上应用不同的图像效果(滤镜),如棕褐色、黑白、模糊等? [关闭]

C#图像处理(各种旋转改变大小柔化锐化雾化底片浮雕黑白滤镜效果)

core image几个滤镜样例 oc版本号和swift版本号