OSX - Loading an image and saving it as a smaller png file using Swift

时间:2016-08-30 04:25:56

标签: swift macos resize nsimage

I am looking for a way to to upload an image file, resize it (in order to reduce the total file size), and then save it as a png. I think there must be a fairly straightforward way of doing this, but hours of searching around have yielded no effective results. I have been able to achieve the desired file size by exporting the image as a compressed JPEG, but I need to preserve transparency. Here is the code I used to get the JPEG:

func chooseImage ()  {
    var image = NSImage()

    //choose image from hard disk
    let panel = NSOpenPanel()
    panel.allowsMultipleSelection = false
    panel.canChooseFiles = true
    panel.canChooseDirectories = false
    panel.runModal()
    panel.allowedFileTypes = ["png", "jpeg", "jpg"]

    let chosenFile = panel.URL

    //convert to NSData and send to Jpeg function
    if chosenFile != nil {
        image = NSImage(contentsOfURL: chosenFile!)!
        let imageData = image.TIFFRepresentation
        self.saveAsJpeg(imageData!, compression: 0.5)
    }
}




func saveAsJpeg (image:NSData, compression:NSNumber)  {
    // make imagerep and define properties
    let imgRep = NSBitmapImageRep(data: image)
    let props = NSDictionary.init(object: compression, forKey: NSImageCompressionFactor)
    let pingy = imgRep?.representationUsingType(NSBitmapImageFileType.NSJPEGFileType, properties: props as! [String : AnyObject])

    //save to disk
    let documentURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
    let folderURL = documentURL.URLByAppendingPathComponent("KKNightlife Data")

    let g = GetUniqueID()
    let fileName = g.getUniqueID() + ".jpeg"

    do {
        try NSFileManager.defaultManager().createDirectoryAtURL(folderURL, withIntermediateDirectories: false, attributes: nil)
    } catch  {
        print("cannot create directory - folder Exists?")
    }
    let url = folderURL.URLByAppendingPathComponent(fileName)

    if let pid = pingy {
        pid.writeToURL(url, atomically: false)
    } else {
        print("error saving image")
    }
}

I attempted to use the following code to scale the image in order to create a smaller .png file, but no matter what values I enter for the size, the resulting file is the same size (both in terms of height/width and overall file size):

func chooseImage (size:String) {
    let panel = NSOpenPanel()
    panel.allowsMultipleSelection = false
    panel.canChooseFiles = true
    panel.canChooseDirectories = false
    panel.runModal()
    panel.allowedFileTypes = ["png", "jpeg", "jpg"]

    let chosenFile = panel.URL

    if chosenFile != nil {
        let image = NSImage(contentsOfURL: chosenFile!)
        self.scaleImage(image!)
    }
}


func scaleImage (image:NSImage) {

    //create resized image
    let newSize = NSSize(width: 10, height: 10)
    var imageRect:CGRect = CGRectMake(0, 0, image.size.width, image.size.height)
    let imageRef = image.CGImageForProposedRect(&imageRect, context: nil, hints: nil)
    let resizedImage = NSImage(CGImage: imageRef!, size: newSize)

    let imageData = resizedImage.TIFFRepresentation

    //make imagerep
    let imgRep = NSBitmapImageRep(data: imageData!)
    let pingy = imgRep?.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties:  [:])

    //save to disk
    let documentURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
    let g = GetUniqueID()
    let fileName = g.getUniqueID() + ".png"

    let folderURL = documentURL.URLByAppendingPathComponent("KKNightlife Data")
    do {
        try NSFileManager.defaultManager().createDirectoryAtURL(folderURL, withIntermediateDirectories: false, attributes: nil)
    } catch  {
        print("cannot create directory - folder Exists?")
    }
    let url = folderURL.URLByAppendingPathComponent(fileName)
    if let pid = pingy {
        pid.writeToURL(url, atomically: false)
        print("image is at \(documentURL)")
    } else {
        print("error saving image")
    }
}

Any suggestions would be greatly appreciated.

1 个答案:

答案 0 :(得分:2)

我终于可以使用此处的扩展程序执行此操作: https://gist.github.com/raphaelhanneken/cb924aa280f4b9dbb480

如果遇到类似的问题,我最终会打电话给他们:

func chooseImage (size:String) {
    let panel = NSOpenPanel()
    panel.allowsMultipleSelection = false
    panel.canChooseFiles = true
    panel.canChooseDirectories = false
    panel.runModal()
    panel.allowedFileTypes = ["png", "jpeg", "jpg"]

    let chosenFile = panel.URL

    if chosenFile != nil {
        let image = NSImage(contentsOfURL: chosenFile!)
        self.scaleImageUsingExtensions(image!)
    }
}

func scaleImageUsingExtensions (image:NSImage){
    let size: NSSize = NSMakeSize(10, 10)
    let resizedImage = image.resizeWhileMaintainingAspectRatioToSize(size)
    let documentURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
    let g = GetUniqueID()
    let fileName = g.getUniqueID() + ".png"

    let folderURL = documentURL.URLByAppendingPathComponent("KKNightlife Data")
    do {
        try NSFileManager.defaultManager().createDirectoryAtURL(folderURL, withIntermediateDirectories: false, attributes: nil)
    } catch  {
        print("cannot create directory - folder Exists?")
    }
    let url = folderURL.URLByAppendingPathComponent(fileName)
    do {

    try resizedImage?.savePNGRepresentationToURL(url)

    }
    catch {
        print("error saving file")
    }
}