裁剪NSImage(macOS)Square不会扭曲

时间:2017-08-03 23:55:52

标签: swift xcode macos swift3 nsimage

我正在使用下面的代码在macOS上调整Swift中的图像大小。这是有效的,但如果图像不是方形,则调整大小会压缩图像。

如何调整图像大小但是在中心绘制并保持比例,如果图像不是正方形,则可以防止压缩?

func resize(image: NSImage, w: CGFloat, h: CGFloat) -> NSImage {
    var destSize = NSMakeSize(CGFloat(w), CGFloat(h))
    var newImage = NSImage(size: destSize)
    newImage.lockFocus()
    image.draw(in: NSMakeRect(0, 0, destSize.width, destSize.height), from: NSMakeRect(0, 0, image.size.width, image.size.height), operation: NSCompositingOperation.sourceOver, fraction: CGFloat(1))
    newImage.unlockFocus()
    newImage.size = destSize
    return NSImage(data: newImage.tiffRepresentation!)!
}

谢谢

2 个答案:

答案 0 :(得分:0)

以下代码行是问题所在:

image.draw(in: NSMakeRect(0, 0, destSize.width, destSize.height), from: NSMakeRect(0, 0, image.size.width, image.size.height), operation: NSCompositingOperation.sourceOver, fraction: CGFloat(1))

您正在从源的整个矩形绘制到目标的整个矩形。因此,这将缩放图像以适合目标,而您希望保持纵横比。您需要确定最终图像的显示方式,并相应地调整源矩形或目标矩形。

例如,如果要缩放结果以便显示整个图像,则需要调整目标矩形的宽度或高度,使它们与源的宽高比相同。

或者,如果要裁剪结果,则需要调整源矩形的宽度或高度,再次保持相同的宽高比。如果要裁剪(例如)顶部和底部,还必须调整源矩形的原点。

其他一些功能如draw(in:from:operation:fraction:)为您处理缩放,因此根据您的需要,它们可能会更好。

答案 1 :(得分:0)

假设您希望将整个源图像放入目标图像空间(或大小),保持原始图像的纵横比并添加一些图像不适合目标的空白区域。< / p>

有三种情况需要考虑。

  1. 源和目标的宽高比相同。

    • 没问题,只需调整大小。
  2. 宽高比目的地比源

    • 高度是驱动值(因为它更小)。
    • 计算从源到目的地的高度比。
    • 使用该比率从源宽度计算目标宽度。
  3. 宽高比目的地高于来源

    • 宽度是驱动值。
    • 计算从源到目的地的宽度比。
    • 使用该比率从源高度计算目标高度。
  4. 我创建了这个函数来计算你需要的大小。

    func calcNewSize(source: NSSize, destination: NSSize) -> NSSize {
        let widthRatio: Float = Float(destination.width) / Float(source.width)
        let heightRatio: Float =  Float(destination.height) / Float(source.height)
        var newSize = NSSize()
    
        print("widthRatio \(widthRatio)   heightRatio \(heightRatio)")
    
        if widthRatio == heightRatio {
            print("use same ratio")
            newSize = destination
        }
        else if widthRatio > heightRatio {
            print("use height ratio")
            newSize.height = source.height * CGFloat(heightRatio)
            newSize.width = source.width * CGFloat(heightRatio)
        }
        else {
            print("use width ratio")
            newSize.height = source.height * CGFloat(widthRatio)
            newSize.width = source.width * CGFloat(widthRatio)
        }
        return newSize
    }