我想知道是否有任何方法可以将视图呈现为图像?就像屏幕截图一样,但我可以为该方法指定任何视图。我知道如何在 ios 中做到这一点。保存视图内容,但我如何在 mac os 中做到这一点?
问问题
3201 次
3 回答
15
有几种方法,但它们都不是完美的。许多问题都与 Layer Backed 视图有关。
如果您没有图层支持或托管视图,则可以使用以下代码:
NSData* data = [mainView dataWithPDFInsideRect:[mainView bounds]];
NSImage *img = [[NSImage alloc] initWithData:data];
如果您使用基于图层的视图:
直到 10.8 对我来说最好的方法是
NSSize mySize = mapImage.bounds.size;
NSSize imgSize = NSMakeSize( mySize.width, mySize.height );
NSBitmapImageRep *bir = [mapImage bitmapImageRepForCachingDisplayInRect:[mapImage bounds]];
[bir setSize:imgSize];
[mapImage cacheDisplayInRect:[mapImage bounds] toBitmapImageRep:bir];
caheImg = [[NSImage alloc]initWithSize:imgSize];
[caheImg addRepresentation:bir];
但在 10.8 中bitmapImageRepForCachingDisplayInRect
停止使用 Layer Backed 视图。
有一个选项可以对您的屏幕进行截图并切出您的视图:
+ (NSImage*) screenCacheImageForView:(NSView*)aView
{
NSRect originRect = [aView convertRect:[aView bounds] toView:[[aView window] contentView]];
NSRect rect = originRect;
rect.origin.y = 0;
rect.origin.x += [aView window].frame.origin.x;
rect.origin.y += [[aView window] screen].frame.size.height - [aView window].frame.origin.y - [aView window].frame.size.height;
rect.origin.y += [aView window].frame.size.height - originRect.origin.y - originRect.size.height;
CGImageRef cgimg = CGWindowListCreateImage(rect,
kCGWindowListOptionIncludingWindow,
(CGWindowID)[[aView window] windowNumber],
kCGWindowImageDefault);
return [[NSImage alloc] initWithCGImage:cgimg size:[aView bounds].size];
}
于 2012-08-14T15:33:41.590 回答
2
我在我的应用程序中使用此代码,效果很好。
但是,如果我将应用程序拖到辅助监视器上,屏幕截图会被丢弃,并且我会捕获错误的矩形。
以下代码修复了该问题(我还从计算中删除了一些多余的数学,其中一个字段被减去然后添加)以防将来有人遇到这个问题:
NSRect originRect = [aView convertRect:[aView bounds] toView:[[aView window] contentView]];
NSArray *screens = [NSScreen screens];
NSScreen *primaryScreen = [screens objectAtIndex:0];
NSRect rect = originRect;
rect.origin.y = 0;
rect.origin.x += [aView window].frame.origin.x;
rect.origin.y = primaryScreen.frame.size.height - [aView window].frame.origin.y - originRect.origin.y - originRect.size.height;
于 2013-07-28T11:16:59.890 回答
2
@Remizorr 的答案在 ObjectiveC 中有效,就像在 macOS High Sierra 10.13.4 下解释的那样。- Xcode 9.2。
它也适用于 layerBacked 视图 ( wantsLayer = true
)。
这是更新的 Swift 版本:
extension NSView {
func snapshotImage() -> NSImage? {
guard let window = window,
let screen = window.screen,
let contentView = window.contentView else { return nil }
let originRect = self.convert(self.bounds, to:contentView)
var rect = originRect
rect.origin.x += window.frame.origin.x
rect.origin.y = 0
rect.origin.y += screen.frame.size.height - window.frame.origin.y - window.frame.size.height
rect.origin.y += window.frame.size.height - originRect.origin.y - originRect.size.height
guard window.windowNumber > 0 else { return nil }
guard let cgImage = CGWindowListCreateImage(rect, .optionIncludingWindow, CGWindowID(window.windowNumber), CGWindowImageOption.bestResolution) else { return nil }
return NSImage(cgImage: cgImage, size: self.bounds.size)
}
}
注意:这甚至适用于 WKWebView 并且它确实拍摄了 WKWebView 视频播放的快照(WKWebViews takeSnapshot 没有);)。
于 2018-05-16T13:55:48.643 回答