2017-01-16 12 views
0

Я сделал много поиска в google, последовали за множеством кода GitHub, без успеха.Как изменить размер - resample - изменить размер файла - NSImage

мне нужно прочитать Jpeg файл, которые имеют DPI = 72, и размер = 16000x1096, например мне нужна, то, чтобы изменить его размер, чтобы сохранить файл в формате JPEG, с 72 DPI, 800x548 пикселей это под OSX, поэтому я могу использовать NSIMAGE, а не UIImage!

Мне все равно, если я потеряю качество!

наконец, после создания сома ма-пу пытается, я поставил здесь свой последний код, и требуется помощь, пожалуйста:

// 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: \ п \ т < (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; цветной ЖК-дисплей)> \ п \ т \ twidth = 1600, height = 1196, bpc = 8, bpp = 32, row bytes = 6400 \ n \ t \ tkCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little \ n \ t \ tis mask? Нет, есть маска? Нет, имеет матовый? Нет, следует интерполировать? Да>»

, как мы видим, содержание, кажется, имеют одинаковый размер, чем оригинал, не так ли?

мне действительно нужна помощь, пожалуйста, я заблокирован, и не найти любое решение.

спасибо за любой ответ, который мог бы мне помочь.

с наилучшими пожеланиями Оливье

+0

я не знаю, но: 144 = 72 + 72 (может быть намек, разделить на 2), и вы кладете 1,0 в высоту/widht, они отношение? Могли бы вы, возможно, на newHeight/oldHeight, в 'property' dict? – 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, что было бы легко заполнить, если это необходимо ,

благодаря Оливье