我想知道是否有任何方法可以渲染图像?就像截图一样,但我可以为该方法指定任何视图。我知道如何在ios中做到这一点。 Saving view content,但我怎样才能在mac os中完成?
答案 0 :(得分: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];
}
答案 1 :(得分: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;
答案 2 :(得分: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拍摄的快照没有);)。
答案 3 :(得分:-1)