2017-01-16 98 views
0

我在google上搜索了很多,后面跟着很多GitHub代码,没有成功。如何调整大小 - resample - 更改文件大小 - NSImage

我需要阅读jpeg文件,其中有一个DPI = 72,和大小= 16000x1096例如 我需要的话,调整其大小,以节省一个JPEG文件,用72 DPI,800x548像素 这在OSX下,所以我可以使用NSIMAGE,而不是UIImage!

我不在乎我是否失去了一些品质!

最后,使SOM MA-NY尝试后,我把这里我最新的代码,并且需要一些帮助,请:

// get source image, jpeg, 1600x1196, 72 dpi 
    let sourceImage = NSImage(contentsOfFile: source) 

    // compute the scale, to have the longest size = 800 pixels. 72 DPI 
    let width = CGFloat(sourceImage!.size.width) 
    let height = CGFloat(sourceImage!.size.height) 
    var scale = CGFloat(800.0/width) 
    if width < height { 
     scale = 800.0/height 
    } 
    let newSize:NSSize = NSSize(width: Int(width * scale), height: Int(height * scale)) 
    print ("new size : " + String(describing: newSize)) 

    // create a new image, with the "small" size 
    let newImage = NSImage(size: NSSize(width: newSize.width, height: newSize.height)) 
    // lockfocus : draw will be done in this image 
    newImage.lockFocus() 
    // interpolation = low, because I don't care of quality 
    NSGraphicsContext.current()?.imageInterpolation = NSImageInterpolation.low 
    // draw the big image, into the small one 
    sourceImage!.draw(in: NSMakeRect(0, 0, newSize.width, newSize.height), from: NSMakeRect(0, 0, width, height), operation: NSCompositingOperation.copy, fraction: CGFloat(1.0)) 
    newImage.unlockFocus() 

    print("newImage size: " + String(describing: newImage.size)) 
    // display : newImage size: 800 x 598 

    let cgRef = newImage.cgImage(forProposedRect: nil, context: nil, hints: nil) 
    let newRep = NSBitmapImageRep(cgImage: cgRef!) 
    newRep.size = newSize 

    let jfifProperties = NSDictionary(dictionary: [kCGImagePropertyJFIFIsProgressive:kCFBooleanTrue]) 
    let properties = NSDictionary(dictionary: [kCGImageDestinationLossyCompressionQuality:1.0, 
               kCGImagePropertyJFIFDictionary:jfifProperties, 
               kCGImagePropertyDPIHeight: 72.0, 
               kCGImagePropertyDPIWidth:72.0, 
               kCGImagePropertyPixelHeight: 1.0, 
               kCGImagePropertyPixelWidth: 1.0 
               ]) 

    let data = newRep.representation(using: .JPEG, properties: properties as! [String : Any]) //[:]) 
    do { 
     let url = URL(string: "file://" + destination) 
     try data?.write(to: url!) //, options: false) 
    } 
    catch let error as NSError { 
     resizeError = error.localizedDescription 
     return false 
    } 

此代码不能正常工作。我得到一个144 DPI和1600 x 1096的文件!

如果我打印,在调试器下,可变newImage,它显示此:

newImage的印刷描述:\ n \吨< (; kCGColorSpaceModelRGB; kCGColorSpaceICCBased彩色LCD)> \ n \吨\ twidth = 1600,height = 1196,bpc = 8,bpp = 32,行字节= 6400 \ n \ t \ tkCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little \ n \ t \ tis掩码?不,有面具?不,有哑光?不,应该插入?是>”

我们可以看到,内容似乎比原来的大小相同,是不是?

我真的需要一些帮助,请,我阻止了,不找任何解决方案。

感谢您的回答,谁可以帮我。

问候 奥利维尔

+0

我不知道,但:144 = 72 + 72(可以是一个提示,除以2),以及你把1.0在高度/ widht,是它们比α你可能会去newHeight/oldHeight,在'properties'字典中? – Larme

回答

1

我找到了解决办法,不过我明白,人们试图帮助我。 谢谢你。

这里是我是如何解决它:

// get source image, jpeg, 1600x1196, 72 dpi 
    let sourceImage = NSImage(contentsOfFile: source) 

    // compute the scale, to have the longest size = 800 pixels. 72 DPI 
    let width = CGFloat(sourceImage!.size.width) 
    let height = CGFloat(sourceImage!.size.height) 
    var scale = CGFloat(resizedLongestSize/width) 
    if width < height { 
     scale = resizedLongestSize/height 
    } 
    let newSize:NSSize = NSSize(width: Int(width * scale), height: Int(height * scale)) 

    // create NSBitmapRep manually, if using cgImage, the resulting size is wrong 
    let rep = NSBitmapImageRep(bitmapDataPlanes: nil, 
           pixelsWide: Int(newSize.width), 
           pixelsHigh: Int(newSize.height), 
           bitsPerSample: 8, 
           samplesPerPixel: 4, 
           hasAlpha: true, 
           isPlanar: false, 
           colorSpaceName: NSDeviceRGBColorSpace, 
           bytesPerRow: Int(newSize.width * 4), 
           bitsPerPixel: 32) 

    let ctx = NSGraphicsContext(bitmapImageRep: rep!) 
    NSGraphicsContext.saveGraphicsState() 
    NSGraphicsContext.setCurrent(ctx) 
    sourceImage!.draw(in: NSMakeRect(0, 0, newSize.width, newSize.height)) 
    ctx?.flushGraphics() 
    NSGraphicsContext.restoreGraphicsState() 

    // Get NSData, and save it 
    let data = rep?.representation(using: .JPEG, properties: [:]) // properties as! [String : Any]) // 
    do { 
     let url = URL(string: "file://" + destination) 
     try data?.write(to: url!) //, options: false) 
    } 
    catch let error as NSError { 
     resizeError = error.localizedDescription 
     return false 
    } 

此代码工作得很好,并提供图片,文件,调整大小,有一组有限的EXIF数据,如果需要的话这将是容易填写。

感谢 奥利弗

相关问题