Reputation: 6500
I'm using the following code to Resize an Image(Keeping Aspect Ratio).When I try to resize an Image whose size is 2432X3648 Pixels to 1800X2700 Pixels The output image origin gets shifted.
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
}
}
Please see the resized sample image.I have marked the Image.The resizing code seems to work fine in other cases.Please advice..
UPDATE: @LeoDabus I have used your code and it produces similar result for output size 1084X2086 Pixels.I had to slightly modify your code - only on a single line as it won't compile.The compiler auto suggested it. 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
}
Upvotes: 4
Views: 691
Reputation: 236360
What was actually wrong was only the canvas size which should be using the new width and height:
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
}
}
Upvotes: 2