[英]WKWebView CALayer to image exports blank image
I'm trying to take a screenshot of webpage but the image is always blank(white).我正在尝试截取网页的屏幕截图,但图像始终为空白(白色)。
I'm using this code to convert CALayer
to Data
(taken from here)我正在使用此代码将
CALayer
转换为Data
(取自此处)
extension CALayer {
/// Get `Data` representation of the layer.
///
/// - Parameters:
/// - fileType: The format of file. Defaults to PNG.
/// - properties: A dictionary that contains key-value pairs specifying image properties.
///
/// - Returns: `Data` for image.
func data(using fileType: NSBitmapImageFileType = .PNG, properties: [String : Any] = [:]) -> Data {
let width = Int(bounds.width * self.contentsScale)
let height = Int(bounds.height * self.contentsScale)
let imageRepresentation = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: width, pixelsHigh: height, bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSDeviceRGBColorSpace, bytesPerRow: 0, bitsPerPixel: 0)!
imageRepresentation.size = bounds.size
let context = NSGraphicsContext(bitmapImageRep: imageRepresentation)!
render(in: context.cgContext)
return imageRepresentation.representation(using: fileType, properties: properties)!
}
}
And then to write the data to file as .png
然后将数据以
.png
格式写入文件
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
{
let d = web.layer?.data() as NSData? //web is the instance of WKWebView
d!.write(toFile: "/Users/mac/Desktop/web.png", atomically: true)
}
But I'm getting a blank(white) png instead of what I expected但是我得到了一个空白(白色)png 而不是我所期望的
1). 1)。 What am I doing wrong?
我究竟做错了什么?
2). 2)。 Is there any other possible ways to get the image representation of webpage(Using swift)?
有没有其他可能的方法来获取网页的图像表示(使用 swift)?
Thank you!谢谢!
Latest Update:最新更新:
Now you can take screenshot of WKWebView
just like WebView
.现在您可以像
WebView
一样截取WKWebView
屏幕截图。
Apple added new method for both iOS and macOS, Apple为 iOS 和 macOS 添加了新方法,
func takeSnapshot(with snapshotConfiguration: WKSnapshotConfiguration?,
completionHandler: @escaping (NSImage?, Error?) -> Void)
But its still in beta.但它仍处于测试阶段。
You can't take a screenshot of WKWebView
.您无法截取
WKWebView
的屏幕截图。 It always returns a blank image.它总是返回一个空白图像。 Even if you try to include
WKWebView
inside another NSView
and take a screenshot, it will give you blank image in place of WKWebView
.即使您尝试将
WKWebView
包含在另一个NSView
并截取屏幕截图,它也会为您提供空白图像代替WKWebView
。
You should use WebView
instead of WKWebView
for your purpose.您应该使用
WebView
而不是WKWebView
来实现您的目的。 Check this question .检查这个问题。
If you are ok with using private frameworks(apple doesn't allow your app in its store), check this GitHub .如果您可以使用私有框架(Apple 不允许在其商店中使用您的应用程序),请查看此GitHub 。 Its written in Obj-C.
它是用 Obj-C 编写的。 I don't know Obj-C so I can't explain what's happening in that code.
我不知道 Obj-C,所以我无法解释该代码中发生了什么。 But it claims to do the work.
但它声称可以完成这项工作。
Your best approach is to use WebView
and use your mentioned extension data()
on the WebView
.你最好的方法是使用
WebView
和使用您提到的扩展data()
上WebView
。
Just a question: Why don't you use phantomJS?只是一个问题:你为什么不使用phantomJS?
PS.附注。 Sorry for the late reply.
这么晚才回复很抱歉。 I didn't see your e-mail.
我没有看到你的电子邮件。
Update: Swift 5 adding to prior.更新: Swift 5添加到之前。
I didn't want controls in the output, so I bound a key sequence to it (local key monitor):我不想在输出中使用控件,所以我将一个键序列绑定到它(本地键监视器):
case [NSEvent.ModifierFlags.option, NSEvent.ModifierFlags.command]:
guard let window = NSApp.keyWindow, let wvc = window.contentViewController as? WebViewController else {
NSSound(named: "Sosumi")?.play()
return true
}
wvc.snapshot(self)
return true
and work within a sandbox environment.并在沙盒环境中工作。 We keep a bunch of user settings in the defaults like where they want snapshots to be captured (~/Desktop), so 1st time around we ask/authenticate, cache it, and the app delegate on subsequent invocations will restore sandbox bookmark(s).
我们将一堆用户设置保留在默认值中,例如他们希望捕获快照的位置 (~/Desktop),因此第一次我们询问/验证、缓存它,随后调用的应用程序委托将恢复沙箱书签.
var webImageView = NSImageView.init()
var player: AVAudioPlayer?
@IBAction func snapshot(_ sender: Any) {
webView.takeSnapshot(with: nil) {image, error in
if let image = image {
self.webImageView.image = image
} else {
print("Failed taking snapshot: \(error?.localizedDescription ?? "--")")
self.webImageView.image = nil
}
}
guard let image = webImageView.image else { return }
guard let tiffData = image.tiffRepresentation else { NSSound(named: "Sosumi")?.play(); return }
// 1st around authenticate and cache sandbox data if needed
if appDelegate.isSandboxed(), appDelegate.desktopData == nil {
let openPanel = NSOpenPanel()
openPanel.message = "Authorize access to Desktop"
openPanel.prompt = "Authorize"
openPanel.canChooseFiles = false
openPanel.canChooseDirectories = true
openPanel.canCreateDirectories = false
openPanel.directoryURL = appDelegate.getDesktopDirectory()
openPanel.begin() { (result) -> Void in
if (result == NSApplication.ModalResponse.OK) {
let desktop = openPanel.url!
_ = self.appDelegate.storeBookmark(url: desktop, options: self.appDelegate.rwOptions)
self.appDelegate.desktopData = self.appDelegate.bookmarks[desktop]
UserSettings.SnapshotsURL.value = desktop.absoluteString
}
}
}
// Form a filename: ~/"<app's name> View Shot <timestamp>"
let dateFMT = DateFormatter()
dateFMT.dateFormat = "yyyy-dd-MM"
let timeFMT = DateFormatter()
timeFMT.dateFormat = "h.mm.ss a"
let now = Date()
let path = URL.init(fileURLWithPath: UserSettings.SnapshotsURL.value).appendingPathComponent(
String(format: "%@ View Shot %@ at %@.png", appDelegate.appName, dateFMT.string(from: now), timeFMT.string(from: now)))
let bitmapImageRep = NSBitmapImageRep(data: tiffData)
// With sandbox clearance to the desktop...
do
{
try bitmapImageRep?.representation(using: .png, properties: [:])?.write(to: path)
// https://developer.apple.com/library/archive/qa/qa1913/_index.html
if let asset = NSDataAsset(name:"Grab") {
do {
// Use NSDataAsset's data property to access the audio file stored in Sound.
player = try AVAudioPlayer(data:asset.data, fileTypeHint:"caf")
// Play the above sound file.
player?.play()
} catch {
Swift.print("no sound for you")
}
}
} catch let error {
NSApp.presentError(error)
NSSound(named: "Sosumi")?.play()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.