【问题标题】:Resizing NSImage Shifts its Origin and Producing Wrong Results调整 NSImage 的大小会改变它的起源并产生错误的结果
【发布时间】:2018-01-28 04:20:17
【问题描述】:

我正在使用以下代码调整图像大小(保持纵横比)。当我尝试将大小为 2432X3648 像素的图像调整为 1800X2700 像素 输出图像原点发生偏移。

extension NSImage {   


  func resizeTo(width: CGFloat, height: CGFloat) -> NSImage {
    let ratioX = width / size.width
    let ratioY = height / size.height
    var ratio = ratioX < ratioY ? ratioX : ratioY
    let newHeight = size.height * ratio
    let newWidth = size.width * ratio
    let canvasSize = CGSize(width: newWidth, height: newHeight)
    let img = NSImage(size: canvasSize)
    img.lockFocus()
    let context = NSGraphicsContext.current()
    context?.imageInterpolation = .high
    draw(in: NSRect(origin: .zero, size: NSSize(width: newWidth,height: newHeight)), from: NSRect(origin: .zero, size: size) , operation: .copy, fraction: 1)
    img.unlockFocus()
    return img
    }


}

请查看调整大小的示例图像。我已经标记了图像。调整大小的代码在其他情况下似乎可以正常工作。请建议..

更新: @LeoDabus我已经使用了你的代码,它为输出大小1084X2086像素产生了类似的结果。我不得不稍微修改你的代码 - 只在一行上,因为它不会编译。编译器自动建议它。 NSGraphicsContext.current()?.imageInterpolation = .high

 func resizeTo(width: CGFloat, height: CGFloat) -> NSImage {
        let ratioX = width / size.width
        let ratioY = height / size.height
        let ratio = ratioX < ratioY ? ratioX : ratioY
        let newHeight = size.height * ratio
        let newWidth = size.width * ratio
        let canvasSize = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))
        let img = NSImage(size: canvasSize)
        img.lockFocus()
        NSGraphicsContext.current()?.imageInterpolation = .high
        draw(in: NSRect(origin: CGPoint(x: (canvasSize.width - (size.width * ratio)) / 2, y: (canvasSize.height - (size.height * ratio)) / 2), size: NSSize(width: newWidth,height: newHeight)), from: NSRect(origin: .zero, size: size), operation: .copy, fraction: 1)
        img.unlockFocus()
        return img

}

【问题讨论】:

  • @LeoDabus 感谢您的回复。原始方法是什么?
  • @LeoDabus 'resizedTo' 方法似乎相同....由于评论中提到的空白问题,我想我已经改变了。
  • @LeoDabus 你看到更新了吗?
  • 我投票结束这个问题作为离题,因为作者已经删除了太多的问题,以至于不清楚问题的意图。

标签: swift xcode macos nsimage


【解决方案1】:

真正的错误只是画布大小应该使用新的宽度和高度:

extension NSImage {
    func resizedTo(width: CGFloat, height: CGFloat) -> NSImage {
        let ratio = min(canvas.width/size.width, canvas.height/size.height)
        let canvasSize = NSSize(width: size.width * ratio, height: size.height * ratio)
        let img = NSImage(size: canvasSize)
        img.lockFocus()
        NSGraphicsContext.current?.imageInterpolation = .high
        draw(in: NSRect(origin: CGPoint(x: (canvasSize.width - (size.width * ratio)) / 2, y: (canvasSize.height - (size.height * ratio)) / 2), size: canvasSize), from: NSRect(origin: .zero, size: size), operation: .copy, fraction: 1)
        img.unlockFocus()
        return img
    }
}

【讨论】:

  • 我收到以下错误Cannot use optional chaining on non-optional value of type '() -&gt; NSGraphicsContext?,所以我按照编译器自动更正并将其更改为NSGraphicsContext.current().imageInterpolation = .high ...您的新代码产生了同样的错误。请指教。
  • 第一个建议是将您的 Swift / Xcode 更新到最新版本。其次,我已经在这里测试了该方法,并且可以正确扩展。确保您已正确设置图像视图约束并且您使用了正确的 imageAlignment
  • 感谢您的回复。我会更新xcode..你有没有测试过将2432X3648像素转换为1800X2700..我不明白你所说的对齐是什么意思......
  • 我不使用图像视图中的图像...我从磁盘加载图像并创建一个 NSImage..我明天将发布更多代码。请检查我告诉你的具体尺寸...代码在某些情况下似乎可以正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-23
  • 1970-01-01
  • 2017-05-12
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
相关资源
最近更新 更多