MENU

在 OSX 应用开发中使用 Swift 生成图像缩略图

• November 25, 2015 • Read: 4811 • Codes

好像 iOS 的比较多,这个是 OSX 下的。

Source

import Foundation
enum ImageResizeType {
    case SizeToFit
    case SizeToFill
    case Crop
    case CropStart
    case CropEnd
}
extension NSImage {
    func resize(newSize:NSSize, resizeType:ImageResizeType) -> NSImage? {
        let sourceImage = self
        let originalSize = sourceImage.size
        guard originalSize.width > 0 && originalSize.height > 0 else {
            return nil
        }
        //计算缩略图区域
        var rect : NSRect!
        var fromRect : NSRect!
        let horizontalRatio = originalSize.width / newSize.width;
        let verticalRatio = originalSize.height / newSize.height;
        let minRatio = min(horizontalRatio, verticalRatio)
        let maxRatio = max(horizontalRatio, verticalRatio)
        var cropOriWidth = newSize.width * minRatio
        var cropOriHeight = newSize.height * minRatio
        if cropOriWidth > originalSize.width {
            cropOriWidth = originalSize.width
        }
        if cropOriHeight > originalSize.height {
            cropOriHeight = originalSize.height
        }
        if resizeType == ImageResizeType.Crop {
            rect = NSRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
            fromRect = NSRect(x: (originalSize.width - cropOriWidth) / 2, y: (originalSize.height - cropOriHeight) / 2, width: cropOriWidth, height: cropOriHeight)
        }else if resizeType == ImageResizeType.CropStart {
            rect = NSRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
            fromRect = NSRect(x: 0, y: 0, width: cropOriWidth, height: cropOriHeight)
        }else if resizeType == ImageResizeType.CropEnd {
            rect = NSRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
            fromRect = NSRect(x: originalSize.width - cropOriWidth, y: originalSize.height - cropOriHeight, width: cropOriWidth, height: cropOriHeight)
        }else if resizeType == ImageResizeType.SizeToFill {
            rect = NSRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
            fromRect = NSRect(x: 0, y: 0, width: originalSize.width, height: originalSize.height)
        }else if resizeType == ImageResizeType.SizeToFit {
            var width = originalSize.width / maxRatio
            var height = originalSize.height / maxRatio
            if width > newSize.width {
                width = newSize.width
            }
            if height > newSize.height {
                height = newSize.height
            }
            rect = NSRect(x: 0, y: 0, width: width, height: height)
            fromRect = NSRect(x: 0, y: 0, width: originalSize.width, height: originalSize.height)
        }
        
        //缩略图
        let resizedImage = NSImage(size: rect.size)
        
        resizedImage.lockFocus()
        sourceImage.drawInRect(rect, fromRect: fromRect, operation: NSCompositingOperation.CompositeSourceOver, fraction: 1.0)
        resizedImage.unlockFocus()
        return resizedImage
    }
    
    // Write to JPG
    func saveToJPEGFile(path:String) -> Bool{
        return self.saveToFile(path, type: .NSJPEGFileType)
    }
    // Write to PNG
    func saveToPNGFile(path:String) -> Bool{
        return self.saveToFile(path, type: .NSPNGFileType)
    }
    func saveToFile(path:String, type:NSBitmapImageFileType) -> Bool{
        guard let imageData = self.TIFFRepresentation else {
            return false
        }
        File(path).mkdirs()
        if type == NSBitmapImageFileType.NSTIFFFileType {
            return imageData.writeToFile(path, atomically: false)
        }
        guard let imageRep = NSBitmapImageRep(data:imageData) else {
            return false
        }
        let imageProps = [NSImageCompressionFactor:0.9]
        return imageRep.representationUsingType(type, properties: imageProps)?.writeToFile(path, atomically: false) == true
    }
}

Usage

NSImage(byReferencingFile: path)?.resize(NSSize(width: width, height: height), resizeType: ImageResizeType.SizeToFit)?.saveToJPEGFile(thumbPath)
Last Modified: January 31, 2023
Archives QR Code Tip
QR Code for this page
Tipping QR Code