I'm loading a 72dpi image into an NSImageView and it looks very blurry on a HiDPI display. How can it get to render perfectly crisp?
I worked out I can improve by adding this entirely non-sensical override to NSImageView, but it doesn't fix it completely.
public class CustomImageView: NSImageView {
public override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
}
}
Here's how it looks by default:
With custom override:
As rendered in Preview:
I've found I can fix this by disabling image interpolation in the graphics context. This override will disable interpolation as long as the image is not larger than the draw rect, so it will look crisp if it fits in the view but retains the interpolation if it needs to scale down.
public class CustomImageView: NSImageView {
public override func draw(_ dirtyRect: NSRect) {
if let image = self.image, image.size.width <= dirtyRect.size.width && image.size.height <= dirtyRect.size.height {
NSGraphicsContext.current?.cgContext.interpolationQuality = .none
}
super.draw(dirtyRect)
NSGraphicsContext.current?.cgContext.interpolationQuality = .default
}
}
Still interested in any other answers or info about this. I'm surprised I can't find anything when searching, seems like it would be a common issue to me.
UPDATE
Setting the interpolation directly on the NSGraphicsContext isn't working on macOS 11 (possibly a bug in the system?). It only works if you target the cgContext.