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

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

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

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

谢谢

奥利弗

【问题讨论】:

    标签: cocoa ios5 core-image


    【解决方案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;
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-11-12
                • 1970-01-01
                • 2017-05-21
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-03-25
                • 2015-08-02
                相关资源
                最近更新 更多