2012-04-05 14 views
27

Estoy utilizando Core Image y me gustaría producir un efecto en blanco y negro en la imagen elegida.¿Cuál es el mejor filtro de imagen central para producir efectos en blanco y negro?

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

Respuesta

54
- (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, pero yo jugaba con ella y no lo encontró tan buena como la mía.

+0

Me alegro que ayude :) – Shmidt

+1

Si alguien está interesado. Lo usé aquí https://github.com/codler/Battery-Time-Remaining/commit/4d0ce73d7b1e954fefba7cbda339b67d77a405d0 – Codler

+0

No funciona en OS X 10.10 Yosemite más = ( – Codler

7

Para crear un efecto monocromo puro, he utilizado CIColorMatrix con la R, G y B parámetros vector todo listo para (0,2125, 0,7154, 0,0721, 0), y el los vectores alpha y bias quedan con sus valores predeterminados.

Los valores son coeficientes de conversión de escala de grises a RGB. 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.

13

aquí es 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; 
} 
+0

'inputIntensity' es' 1' por defecto, no es necesario et de forma manual. –

4

Con respecto a las respuestas que sugieren utilizar CIColorMonochrome: En la actualidad hay unos filtros en escala de grises dedicados disponibles desde iOS7 (y OS X 10.9):

  • CIPhotoEffectTonal

    imite una película fotográfica en blanco y negro sin cambiar significativamente el contraste.

  • CIPhotoEffectNoir:

    imitar blanco y negro de la fotografía de película con contraste exagerada

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

4

Aquí está la solución puntuación superior convertido 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 
} 
2

Aquí está la respuesta más le gusta de @Shmidt escrito como una extensión 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 
    } 
} 
0

macOS (NSImage) Swift versión 3 de @ conversión de @ respuesta de Shmidt de FBente:

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 
    } 
} 
0

He intentado con la solución Shmidt, pero me parece demasiado expuesta en el iPad Pro. Estoy utilizando 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; 
} 
Cuestiones relacionadas