简体   繁体   English

在NSImage上使用lockFocus时,如何强制非视网膜图像?

[英]How do you force a non-retina image when using lockFocus on an NSImage?

I have the following code to create an image of a circle of 200x200 pixels. 我有以下代码来创建一个200x200像素的圆圈的图像。 This isn't for on-screen usage, so I've manually added an NSBitmapImageRep to the image before locking the focus and drawing. 这不是在屏幕上使用的,因此在锁定焦点和绘图之前,我已向图像手动添加了NSBitmapImageRep。

let ovalSize = CGSize(width: 200, height: 200)
let ovalPath = NSBezierPath(ovalIn: CGRect(origin: CGPoint.zero, size: ovalSize))
let ovalImage = NSImage(size: ovalSize)
let imageRep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: 200, pixelsHigh: 200, bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: true, colorSpaceName: .deviceRGB, bitmapFormat: [.alphaFirst, .thirtyTwoBitLittleEndian], bytesPerRow: 0, bitsPerPixel: 0)
ovalImage.addRepresentation(imageRep!)
ovalImage.lockFocus()
NSColor(deviceWhite: 1, alpha: 1).setFill()
ovalPath.fill()
ovalImage.unlockFocus()

However if I Quick Look at ovalImage it has been rendered at 400x400, and printing the representations of ovalImage produces the following: 但是,如果我快速查看ovalImage它已以400x400渲染,打印ovalImage的表示将产生以下结果:

[<NSCGImageSnapshotRep:0x60000175bf00 cgImage=<CGImage 0x101612d30> (DP)
<<CGColorSpace 0x60000260cba0> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Color LCD)>
    width = 400, height = 400, bpc = 8, bpp = 32, row bytes = 1600 
    kCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little  | kCGImagePixelFormatPacked 
    is mask? No, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes>]

The docs for lockFocus mention that a representation will be added if one isn't available, so I'm confused as to why the one I'm adding is being replaced? lockFocus的文档中提到,如果没有一种表示形式,则会添加一种表示形式,因此,我对为什么要替换的一种表示形式感到困惑。

I think what you need is "Drawing Offscreen Images Using a Block-Based Drawing Method to Support High Resolution Displays" . 我认为您需要的是“使用基于块的绘制方法绘制离屏图像以支持高分辨率显示”

You can do this: 你可以这样做:

let ovalPath = NSBezierPath(ovalIn: CGRect(origin: CGPoint.zero, size: NSMakeSize(200, 200)))
let ovalImage = NSImage(size: NSMakeSize(200, 200), flipped: false) { (rect) -> Bool in
    NSColor(deviceWhite: 1, alpha: 1).setFill()
    ovalPath.fill()
    return true
}

or 要么

let ovalSize = CGSize(width: 200, height: 200)
let ovalPath = NSBezierPath(ovalIn: CGRect(origin: CGPoint.zero, size: NSMakeSize(200, 200)))
let imageRep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: 200, pixelsHigh: 200, bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: true, colorSpaceName: .deviceRGB, bitmapFormat: [.alphaFirst, .thirtyTwoBitLittleEndian], bytesPerRow: 0, bitsPerPixel: 0)
NSGraphicsContext.saveGraphicsState()
NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: imageRep!)
NSColor(deviceWhite: 1, alpha: 1).setFill()
ovalPath.fill()
NSGraphicsContext.restoreGraphicsState()
let ovalImage = NSImage(size: ovalSize)
ovalImage.addRepresentation(imageRep!)

I didn't know the reason why the representation you are adding is being replaced, but you should treat NSImage and its image representations as immutable objects . 我不知道为什么要替换您要添加的表示形式,但是您应该将NSImage及其图像表示形式视为不可变对象

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM