web-dev-qa-db-fra.com

Quel est le meilleur filtre?

J'utilise Core Image et souhaite créer un effet noir et blanc sur l'image choisie. 

Idéalement, j'aimerais avoir accès au même type d'options que celles disponibles sur Photoshop, à savoir les rouges, cyan, verts, bleus et magenta. L'objectif étant de créer différents types d'effet noir et blanc.

Est-ce que quelqu'un sait quel filtre serait le mieux pour manipuler ce type d'options? Sinon, est-ce que quelqu'un connaît une bonne approche pour créer l'effet noir et blanc en utilisant d'autres filtres?

Merci

Oliver

28
ORStudios
- (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 .: Pour iOS6, il existe un filtre CIColorMonochrome, mais j'ai joué avec et je ne l'ai pas trouvé aussi bon que le mien.

56
Shmidt

voici l'exemple avec 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;
}
13
wasikuss

Pour créer un effet monochrome pur, j’ai utilisé CIColorMatrix avec les paramètres de vecteur R, V et B définis sur (0.2125, 0.7154, 0.0721, 0) et les vecteurs alpha et biais laissés avec leurs valeurs par défaut.

Les valeurs sont les coefficients de conversion RVB en niveaux de gris que j'ai consultés à un moment donné sur les internets. En modifiant ces coefficients, vous pouvez modifier la contribution des canaux d’entrée. En mettant à l'échelle chaque copie du vecteur et en définissant éventuellement un vecteur de biais, vous pouvez coloriser la sortie.

7
Jens Ayton

Voici la solution la mieux notée convertie en Swift (iOS 7 et versions supérieures):

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
}
6
DerGote

En ce qui concerne les réponses suggérant d'utiliser CIColorMonochrome: Il existe maintenant quelques filtres en niveaux de gris dédiés disponibles sur iOS7 (et OS X 10.9):

  • CIPhotoEffectTonal

    imitez un film de photographie en noir et blanc sans altérer de manière significative le contraste.

  • CIPhotoEffectNoir:

    imiter un film de photographie en noir et blanc avec un contraste exagéré

Source: https://developer.Apple.com/library/mac/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html

4
Clafou

Voici la réponse la plus appréciée de @Shmidt écrite sous la forme d'une extension UIImage avec une mise à jour des performances dans 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
    }
}
2
FBente

J'ai essayé la solution Shmidt mais elle me semble trop exposée sur iPad Pro. J'utilise seulement la première partie de sa solution, sans le filtre d'exposition:

- (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;
}
0
SpaceDog

macOS (NSImage) Swift 3 version de la conversion de @ FBente de la réponse 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
    }
}
0
Alex