webentwicklung-frage-antwort-db.com.de

Was ist der beste Core Image-Filter, um Schwarz-Weiß-Effekte zu erzielen?

Ich verwende Core Image und möchte einen Schwarz-Weiß-Effekt auf das ausgewählte Bild erzeugen.

Im Idealfall hätte ich gerne Zugriff auf dieselben Optionen, die in Photoshop verfügbar sind, z. B. Rot, Cyan, Grün, Blau und Magenta. Das Ziel ist es, verschiedene Arten von Schwarz-Weiß-Effekten zu erzeugen.

Weiß jemand, welcher Filter am besten geeignet ist, um diese Art von Optionen zu manipulieren? Wenn nicht, weiß jemand, wie man den Schwarz-Weiß-Effekt mit anderen Filtern erzeugt?

Vielen Dank

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 .: Für iOS6 gibt es CIColorMonochrome filter, aber ich spielte damit und fand es nicht so gut wie meins.

56
Shmidt

hier ist ein Beispiel mit 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

Um einen reinen Monochromeffekt zu erzeugen, habe ich CIColorMatrix verwendet, wobei die R-, G- und B-Vektorparameter auf (0.2125, 0.7154, 0.0721, 0) und die Alpha- und Bias-Vektoren mit ihren Standardwerten eingestellt sind.

Die Werte sind RGB-zu-Graustufen-Umrechnungskoeffizienten, die ich irgendwann im Internet nachgeschlagen habe. Durch Ändern dieser Koeffizienten können Sie den Beitrag der Eingangskanäle ändern. Durch Skalieren jeder Kopie des Vektors und optionales Setzen eines Vorgabevektors können Sie die Ausgabe farbig gestalten.

7
Jens Ayton

Hier ist die am besten bewertete Lösung, die in Swift konvertiert wurde (iOS 7 und höher):

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

Zu den Antworten, die auf die Verwendung von CIColorMonochrome hinweisen: Es gibt jetzt einige dedizierte Graustufenfilter von iOS7 (und OS X 10.9):

  • CIPhotoEffectTonal

    imitieren eines Schwarzweiß-Fotofilms, ohne den Kontrast wesentlich zu verändern.

  • CIPhotoEffectNoir:

    imitieren eines Schwarzweiß-Fotofilms mit übertriebenem Kontrast

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

4
Clafou

Hier ist die beliebteste Antwort von @Shmidt, die als UIImage-Erweiterung mit einem Leistungsupdate in Swift geschrieben wurde:

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

Ich habe die Shmidt-Lösung ausprobiert, aber sie erscheint mir auch auf dem iPad Pro überbelichtet. Ich verwende nur den ersten Teil seiner Lösung ohne den Belichtungsfilter:

- (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 von @ FBentes Konvertierung von @ Shmidts Antwort:

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