I am trying to capture the image that the webview is displaying to the user, so I can some color analysis of the web page. When I try to get the image from it's parent, I am basically getting a white box, even though the page has rendered:
func makeImageSnapshot()-> (NSImage)
{
let imgSize = self.view.bounds.size
let bir = self.viewbitmapImageRepForCachingDisplayInRect(self.webView!.view.bounds)
bir.size = imgSize
self.webView.cacheDisplayInRect(self.view.bounds, toBitmapImageRep:bir)
let image = NSImage(size:imgSize)
image.addRepresentation(bir)
self.image = image
return image
}
func saveSnapshot()
{
let imgRep = self.image!.representations[0]
let data = imgRep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: nil)
data.writeToFile("/tmp/file.png", atomically: false)
}
It looks to me like I can't get access to the properties of the actual view (in this case the bounds) inside of the webView. When I try to access it, the compiler barfs:
/Users/josh/Canary/MacOsCanary/canary/canary/Modules/Overview/Overview.swift:55:37: '(NSView!, stringForToolTip: NSToolTipTag, point: NSPoint, userData: UnsafePointer<()>) -> String!' does not have a member named 'bounds'
My guess is that this is happening due to the extensions approach used by OS X and iOS. Any ideas, or should I just go back to using the legacy WebView?
I realise the question was for Mac OS X, but I found this page whilst searching for an iOS solution. My answer below doesn't work on Mac OS X as the drawViewHierarchyInRect() API call is currently iOS only, but I put it here for reference for other iOS searchers.
This Stackoverflow answer solved it for me on iOS 8 with a WKWebView. That answer's sample code is in Objective-C but the Swift equivalent to go in a UIView sub-class or extension would be along the lines of the code below. The code ignores the return value of drawViewHierarchyInRect(), but you may want to pay attention to it.
func imageSnapshot() -> UIImage
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, true, 0);
self.drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true);
let snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshotImage;
}
Swift 3
extension WKWebView {
func screenshot() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, true, 0);
self.drawHierarchy(in: self.bounds, afterScreenUpdates: true);
let snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshotImage;
}
}
Note: This solution only works on iOS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With