我有一个应用程序想要为其制作 Mac App Store 屏幕截图。这是一个菜单栏应用程序,因此定期截图会导致分辨率非常低的图像。我已经弄清楚如何将应用程序的视图屏幕截图为 PDF,然后将 PDF 转换为 SVG,然后将 SVG 转换为 PNG。这是获取屏幕截图的一种迂回方式,但它有效,而且可以以高分辨率制作,这正是我想要的。我的问题是,有没有办法在我的电脑桌面上做类似的事情?我基本上想截取桌面视图的屏幕截图,并将其写入 PDF,就像我对应用程序视图所做的那样。
这是我目前为自己的应用程序视图执行此操作的方法。
这是我的 NSPopover 子类上的一个函数,所以这就是
contentViewController!.view
的来源。
let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("\(Int(Date().timeIntervalSince1970 * 1000)).pdf") as CFURL
let size = Defaults[.windowSize]
var mediaBox = NSRect(origin: .zero, size: size)
let gc = CGContext(url, mediaBox: &mediaBox, nil)!
let nsgc = NSGraphicsContext(cgContext: gc, flipped: false)
NSGraphicsContext.current = nsgc
gc.beginPDFPage(nil); do {
let view = contentViewController!.view as! NSHostingView<ContentView>
gc.saveGState(); do {
gc.drawFlipped(rect: mediaBox) {
view.layer?.render(in: gc)
}
}; gc.restoreGState()
}; gc.endPDFPage()
NSGraphicsContext.current = nil
gc.closePDF()
我基本上想知道是否有办法用访问桌面视图的东西替换
contentViewController!.view
(最好是菜单栏。)
也许这对你不起作用,但我希望如此。因此,通过这样做,可以使用 Core Graphics 框架中的
CGWindowListCreateImage
函数。该函数创建指定窗口的图像。
示例:
let windowListOption = CGWindowListOption(arrayLiteral: .optionIncludingWindow)
let windowID = CGWindowID(yourWindow.windowNumber)
let imageOption = CGWindowImageOption(arrayLiteral: .boundsIgnoreFraming)
let image = CGWindowListCreateImage(CGRect.null, windowListOption, windowID, imageOption)
在上面的代码中,
yourWindow
是你要捕获的窗口。您可以从 NSWindow
实例获取它。 CGWindowListCreateImage
函数返回一个 CGImage
,然后您可以在上下文中绘制它。
如果您想捕获整个屏幕,包括菜单栏,您可以使用
NSBitmapImageRep
类创建屏幕的位图表示形式,然后在您的上下文中绘制它。
示例是:
let screenRect = NSScreen.main!.frame
let bitmap = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(screenRect.width), pixelsHigh: Int(screenRect.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: .calibratedRGB, bytesPerRow: 0, bitsPerPixel: 0)!
let context = NSGraphicsContext(bitmapImageRep: bitmap)!
NSGraphicsContext.saveGraphicsState()
NSGraphicsContext.current = context
yourWindow.contentView!.draw(screenRect)
NSGraphicsContext.restoreGraphicsState()
yourWindow
是您要捕获的窗口。 draw
的 NSView
方法在目标的指定矩形中绘制视图。然后,您可以使用 bitmap
创建图像并在您的上下文中绘制它。
*由于沙箱限制,此方法不会捕获不属于您的应用程序的窗口内容。此外,捕获菜单栏是不可能的,因为它是一个单独的进程,无法由应用程序捕获。