产生黑白效果的最佳 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)提供了一些专用的灰度滤镜:
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 滤镜是啥?的主要内容,如果未能解决你的问题,请参考以下文章
如何在位图上应用不同的图像效果(滤镜),如棕褐色、黑白、模糊等? [关闭]