cocoa - tipo - ¿Cuál es el mejor filtro de imagen central para producir efectos en blanco y negro?
editor de fotos (8)
Aquí está la respuesta más deseada de @Shmidt escrita como una extensión de UIImage con una actualización de rendimiento en 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
}
}
Estoy utilizando Core Image y me gustaría producir un efecto en blanco y negro en la imagen elegida.
Idealmente, me gustaría tener acceso al mismo tipo de opciones que están disponibles en Photoshop, es decir, rojos, cian, verdes, azules y magentas. El objetivo es crear diferentes tipos de efectos en blanco y negro.
¿Alguien sabe qué filtro sería el mejor para manipular este tipo de opciones? Si no, ¿alguien sabe de un buen enfoque para crear el efecto en blanco y negro con otros filtros?
Gracias
Oliver
Aquí está la solución mejor valorada convertida a Swift (iOS 7 y superior):
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
}
Con respecto a las respuestas que sugieren el uso de CIColorMonochrome
: ahora hay algunos filtros de escala de grises dedicados disponibles de iOS7 (y OS X 10.9):
- CIPhotoEffectTonal
imite una película fotográfica en blanco y negro sin alterar significativamente el contraste.
- CIPhotoEffectNoir:
imitar una película fotográfica en blanco y negro con un contraste exagerado
He probado la solución Shmidt, pero me parece demasiado expuesta en iPad Pro. Estoy usando solo la primera parte de su solución, sin el filtro de exposición:
- (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;
}
Para crear un efecto monocromático puro, he utilizado CIColorMatrix
con los parámetros del vector R, G y B, todos establecidos en (0.2125, 0.7154, 0.0721, 0), y los vectores alfa y diagonal que quedan con sus valores predeterminados.
Los valores son RGB a coeficientes de conversión en escala de grises. Miré en algún momento las internets. Al cambiar estos coeficientes, puede cambiar la contribución de los canales de entrada. Al escalar cada copia del vector y, opcionalmente, establecer un vector de polarización, puede colorear el resultado.
Versión de macOS (NSImage) Swift 3 de la conversión de @FBente de la respuesta de @ 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
}
}
aquí está el ejemplo con 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;
}
- (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;
}
Upd .: Para iOS6
hay CIColorMonochrome
filtro CIColorMonochrome
, pero jugué con él y lo encontré no tan bueno como el mío.