2012-04-05 9 views
27

Używam Core Image i chciałbym uzyskać czarno-biały efekt na wybranym obrazie.Jaki jest najlepszy filtr Core Image do tworzenia czarno-białych efektów?

Idealnie chciałbym mieć dostęp do tego samego rodzaju opcji, które są dostępne w Photoshopie, np. Reds, Cyjan, Zieloni, Blues i Magenta. Celem jest stworzenie różnych rodzajów efektu czarno-białego.

Czy ktoś wie, jaki filtr byłby najlepszy do manipulowania tego rodzaju opcjami? Jeśli nie, nikt nie wie o dobrym podejściu do tworzenia czarno-białego efektu za pomocą innych filtrów?

Dzięki

Oliver

Odpowiedz

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 .: Dla iOS6 jest CIColorMonochrome filtr, ale grałem z nim i okazało się, że nie tak dobre jak moje.

+0

Cieszę się, że to pomaga :) – Shmidt

+1

Jeśli ktoś jest zainteresowany. Użyłem go tutaj https://github.com/codler/Battery-Time-Remaining/commit/4d0ce73d7b1e954fefba7cbda339b67d77a405d0 – Codler

+0

To nie działa w OS X 10.10 Yosemite już = ( – Codler

7

celu utworzenia czystego efekt monochromatyczne wcześniej używanych CIColorMatrix z R, G i B parametry ustawione na wektor (0,2125, 0.7154, 0.0721, 0), a Wektory alfa i stronniczości pozostawione z domyślnymi wartościami.

Wartości współczynników konwersji RGB do skali szarości w pewnym momencie znalazłem w Internecie. Zmieniając te współczynniki, można zmienić wkład kanałów wejściowych. Poprzez skalowanie każdej kopii wektora i opcjonalnie ustawianie wektora odchylenia, można zmienić kolorystykę wyjściową.

13

tutaj jest przykład z 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' to domyślnie' 1', bez konieczności s i to ręcznie. –

4

W odniesieniu do odpowiedzi sugerujące użycie CIColorMonochrome: Istnieje obecnie kilka dedykowanych filtrów skali szarości dostępne od iOS7 (i OS X 10.9):

  • CIPhotoEffectTonal

    naśladuj czarno-biały filmik bez znaczącej zmiany kontrastu.

  • CIPhotoEffectNoir:

    naśladować czarno-białej fotografii filmowej z przesadną przeciwieństwie

Źródło: https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html

4

Oto top rozwiązanie oceniono konwertowane do Swift (iOS 7 i nowsze):

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

Oto najbardziej lubił odpowiedź od @Shmidt napisany jako rozszerzenie UIImage z aktualizacją wyników w 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 3 wersji @ konwersji FBente dnia @ odpowiedź Shmidt za:

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

Próbowałem rozwiązania Shmidt, ale wydaje mi się zbyt wyeksponowany na iPad Pro. Używam tylko pierwszej części jego rozwiązania, bez filtra ekspozycji:

- (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; 
} 
Powiązane problemy