user3390652
user3390652

Reputation: 142

Swift 3 Colour Space macOS not IOS

How can I convert an RGB image into its grayscaled colour space? I can find a lot of code for iOS but non for macOS.. And the Apple's documentations are all in objective C....

    let width = image.size.width
    let height = image.size.height
    let imageRect = NSMakeRect(0, 0, width, height);
    let colorSpace = CGColorSpaceCreateDeviceGray();


    let bits = image.representations.first as! NSBitmapImageRep;
    bitmap!.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: nil)


    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);
    context.draw(image.cgImage!, in : imageRect);// and this line is wrong obviously..

This is what I have got so far..just copy and pasting from the internet.. but I have no idea on how to go further...

Upvotes: 1

Views: 913

Answers (2)

user3390652
user3390652

Reputation: 142

I have found an interesting way to do this.. My code are simply copied from the three sources below.

how to create grayscale image from nsimage in swift?

Greyscale Image using COCOA and NSImage

Changing the Color Space of NSImage: The second reply

My Code:

func saveImage(image:NSImage, destination:URL) throws{
    let rep = greyScale(image);
    var data = rep.representation(using: NSJPEGFileType, properties: [:]);
    try data?.write(to: destination);

}

// rgb2gray
func greyScale(image: NSImage) -> NSBitmapImageRep{
    let w = image.size.width
    let h = image.size.height
    let imageRect : NSRect! = NSMakeRect(0,0, w, h);
    let colourSpace : ColourSpace! = CGColorSpaceCreateDeviceGray();
    let context : CGContext! = CGContext(data: nil, width: Int(w), 
                                        height: Int(h), bitsPerComponent: 8, 
                                        bytesPerRow: 0, space: colorSpace, 
                                        bitmapInfo: CGImageAlphaInfo.none.rawValue);        

    context.draw(nsImageToCGImage(image: image), in: imageRect);
    let greyImage : CGImage! = context.makeImage();

    return NSBitmapImageRep(cgImage: greyImage);
}


func nsImageToCGImage(image: NSImage) -> CGImage{
    if let imageData = image.tiffRepresentation as NSData! {
        let imageSource : CGImageSource! = CGImageSourceCreateWithData(imageData, 
                                        nil);
        let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil);
        return image;
    }
    return nil;
}

I am still trying to understand the principle behind.

Upvotes: 2

Code Different
Code Different

Reputation: 93171

You can try CIFilter. The annoyance is that you have to convert back and forth between NSImage and CIImage:

import Cocoa
import CoreImage

let url = Bundle.main.url(forResource: "image", withExtension: "jpg")!
let image = CIImage(contentsOf: url)!

let bwFilter = CIFilter(name: "CIColorControls", withInputParameters: ["inputImage": image, "inputSaturation": 0.0])!

if let ciImage = bwFilter.outputImage {
    let rep = NSCIImageRep(ciImage: ciImage)
    let nsImage = NSImage(size: rep.size)
    nsImage.addRepresentation(rep)
    // nsImage is now your black-and-white image
}

Upvotes: 1

Related Questions