2

I am trying to convert a UIImage to GrayScale. All it make is totally a black image.

func convertToGrayScale2(image: UIImage) -> UIImage {
    let imageRect:CGRect = CGRect(x:0, y:0, width:image.size.width, height: image.size.height)
    let colorSpace = CGColorSpaceCreateDeviceGray()
    let width = image.size.width
    let height = image.size.height

    let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue)
    let context = CGContext(data: nil, width: Int(width), height: Int(height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)
    let imageRef = context!.makeImage()
    context?.draw(imageRef!, in: imageRect)
    let newImage = UIImage(cgImage: imageRef!)

    return newImage
}

Is there anything wrong with the code? I need help with existing code. It was working previously. Suddenly its not working.

Rubaiyat Jahan Mumu
  • 3,887
  • 1
  • 33
  • 35

3 Answers3

5
func convertToGrayScale(image: UIImage) -> UIImage {
        let imageRect:CGRect = CGRect(x:0, y:0, width:image.size.width, height: image.size.height)
        let colorSpace = CGColorSpaceCreateDeviceGray()
        let width = image.size.width
        let height = image.size.height

        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue)
        let context = CGContext(data: nil, width: Int(width), height: Int(height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)
        //have to draw before create image

        context?.draw(image.cgImage!, in: imageRect)
        let imageRef = context!.makeImage()
        let newImage = UIImage(cgImage: imageRef!)

        return newImage
    }
Rubaiyat Jahan Mumu
  • 3,887
  • 1
  • 33
  • 35
2

You can use this function instead:

func convertImageToDifferentColorScale(with originalImage:UIImage, imageStyle:String) -> UIImage {
    let currentFilter = CIFilter(name: imageStyle)
    currentFilter!.setValue(CIImage(image: originalImage), forKey: kCIInputImageKey)
    let output = currentFilter!.outputImage
    let context = CIContext(options: nil)
    let cgimg = context.createCGImage(output!,from: output!.extent)
    let processedImage = UIImage(cgImage: cgimg!)
    return processedImage
}

And here is the example of how you use:

 let newImage = convertImageToDifferentColorScale(with: UIImage(named: "0318_1")!, imageStyle: "CIPhotoEffectNoir")
 testingImageView.image = newImage

In imageStyle part, there are several different kind of style like below:

 CIColorCrossPolynomial
 CIColorCube
 CIColorCubeWithColorSpace
 CIColorInvert
 CIColorMap
 CIColorMonochrome
 CIColorPosterize
 CIFalseColor
 CIMaskToAlpha
 CIMaximumComponent
 CIMinimumComponent
 CIPhotoEffectChrome
 CIPhotoEffectFade
 CIPhotoEffectInstant
 CIPhotoEffectMono
 CIPhotoEffectNoir

And 'CIPhotoEffectNoir' is one choice that can give you gray scale.

Joe
  • 8,868
  • 8
  • 37
  • 59
Ding Qiu
  • 64
  • 3
  • This will not create an image with DeviceGray color space( kcGColorSpaceModelMonochrome), but kCGColorSpaceDeviceRGB. If the output of this solution were to be used as a masking image cgImage.masking() e.g., it would not work, since that would require DeviceGray color space. – joqqy Aug 18 '22 at 22:42
0

A possible alternative maybe to use CoreImage filters. Please refer to the following SO Post and its Accepted Answer. Hope it helps. Happy Coding!

Community
  • 1
  • 1
Md. Ibrahim Hassan
  • 5,359
  • 1
  • 25
  • 45