2017-04-13 1 views
0

現在、スウィフトを使用して画像を拡大/縮小しようとしています。このshouldnt私は30分でC#でスケーリングソリューションを実装しているので、これは難しい作業です。しかし、私は今2日間立ち往生しています。画像の拡大/縮小OSX Swift

私は、スタック・ポストを介してグーグル/クロールを試みましたが、役に立たないです。私は、人々が使用見てきた二つの主な解決策は以下のとおりです。

A function written in Swift to resize an NSImage proportionately

resizeNSImage.swift

An Obj C Implementation of the above link

だから私は、最も効率的/少なくともCPUに負荷をかけソリューションを使用することを好むだろう、これは私の研究によればオプション2です。オプション2のためにNSImage.lockfocus()NSImage.unlockFocusを使用すると、イメージは非網膜上のMacでうまくスケールされますsであるが、網膜の倍率は倍増する。私はこれがRetina macsのピクセル密度によるものであることを知っていますが、予想されますが、私はHiDPIの仕様を無視し、通常のスケール操作を行うスケーリングソリューションが必要です。

これは私にオプション1のさらなる研究を依頼しました。それはサウンド機能のように思えますが、文字通り入力画像の縮尺を変えず、返された画像を保存するときにファイルサイズを2倍にします(おそらくはピクセル密度による)。私はまったく同じ問題を抱えている人と別のスタックポストを見つけました。まったく同じ実装(found here)を使っています。 2つの提案された答えのうち、最初のものは動作しませんでした。もう1つは、私が使用しようとしている他の実装です。

投稿者投稿者Swift - 回答、Obj Cとは対照的に、私は非常に感謝します!

編集:ここでは は、第1の溶液の私の実装のコピーだ - 私は2つの機能にそれを分けました:

func getSizeProportions(oWidth: CGFloat, oHeight: CGFloat) -> NSSize { 

    var ratio:Float = 0.0 
    let imageWidth = Float(oWidth) 
    let imageHeight = Float(oHeight) 

    var maxWidth = Float(0) 
    var maxHeight = Float(600) 

    if (maxWidth == 0) { 
     maxWidth = imageWidth 
    } 

    if(maxHeight == 0) { 
     maxHeight = imageHeight 
    } 

    // Get ratio (landscape or portrait) 
    if (imageWidth > imageHeight) { 
     // Landscape 
     ratio = maxWidth/imageWidth; 
    } 
    else { 
     // Portrait 
     ratio = maxHeight/imageHeight; 
    } 

    // Calculate new size based on the ratio 
    let newWidth = imageWidth * ratio 
    let newHeight = imageHeight * ratio 

    return NSMakeSize(CGFloat(newWidth), CGFloat(newHeight)) 
} 


func resizeImage(image:NSImage) -> NSImage { 
    print("original: ", image.size.width, image.size.height) 

    // Cast the NSImage to a CGImage 
    var imageRect:CGRect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height) 
    let imageRef = image.cgImage(forProposedRect: &imageRect, context: nil, hints: nil) 

    // Create a new NSSize object with the newly calculated size 
    let newSize = NSSize(width: CGFloat(450), height: CGFloat(600)) 
    //let newSize = getSizeProportions(oWidth: CGFloat(image.size.width), oHeight: CGFloat(image.size.height)) 

    // Create NSImage from the CGImage using the new size 
    let imageWithNewSize = NSImage(cgImage: imageRef!, size: newSize) 

    print("scaled: ", imageWithNewSize.size.width, imageWithNewSize.size.height) 

    return NSImage(data: imageWithNewSize.tiffRepresentation!)! 
} 

EDIT 2:

としてはZneakによって指摘私はディスクに返されたイメージを保存する必要があります - 両方の実装を使用して、私の保存関数は、ディスクにファイルを正常に書き込みます。私は私の関数が私の現在のサイズ変更の実装にねじ込むことができ、保存と思ういけないが、私は念のためにとにかくそれを添付しました:

func saveAction(image: NSImage, url: URL) { 

    if let tiffdata = image.tiffRepresentation, 
    let bitmaprep = NSBitmapImageRep(data: tiffdata) { 

    let props = [NSImageCompressionFactor: Appearance.imageCompressionFactor] 
    if let bitmapData = NSBitmapImageRep.representationOfImageReps(in: [bitmaprep], using: .JPEG, properties: props) { 

     let path: NSString = "~/Desktop/out.jpg" 
     let resolvedPath = path.expandingTildeInPath 

     try! bitmapData.write(to: URL(fileURLWithPath: resolvedPath), options: []) 

     print("Your image has been saved to \(resolvedPath)") 
    } 
} 
+0

「するべきか」「するべきではない」?簡単なことは簡単です。また、画面上に表示したり、ディスクやその他のものに書き戻したりする目的で行っていますか?より大きいか小さいサイズへのスケーリング? – zneak

+0

はOP: – amartin94

+0

を編集しました。ディスクに書き戻すために縮小しました。 – amartin94

答えて

0

この問題が発生して誰にも - 私が見つけることを試みて数え切れないほどの時間を費やしてしまいましたこれを行う方法、およびちょうど画面(通常のMac用1、網膜のための2)の倍率を取得してしまった...コードは次のようになります。

func getScaleFactor() -> CGFloat { 
    return NSScreen.main()!.backingScaleFactor 
} 

その後、あなたはスケールファクタにあなたを持っていたら、通常のスケールまたは網膜の寸法の半分のいずれか:

if (scaleFactor == 2) { 
    //halve size proportions for saving on Retina Macs 
    return NSMakeSize(CGFloat(oWidth*ratio)/2, CGFloat(oHeight*ratio)/2) 
} else { 
    return NSMakeSize(CGFloat(oWidth*ratio), CGFloat(oHeight*ratio)) 
} 
+0

特定の倍率をチェックする代わりに、 CGFloat(oWidth * ratio)/ scaleFactor'となります。こうすることで、バッキングスケールファクターが他の値であるデバイス/モードをAppleが導入しても、コードは正しく動作します。しかし、まずは0をチェックしてください! – DarkDust

関連する問題