webview.capturePage doesn't capture full page on retina display


I’ve been struggling with capturing a webview on a retina display and am hoping someone can help out.

I have a simple application that opens a webview and allows the user to take a screenshot of the display area. On non-retina displays, everything is fine. On a retina display, the captured images is twice the dimensions of the display area (expected because the scale factor is 2). However, the actual image that is captured is only half of the viewable dimensions.

This is an OS screenshot of the electron application. You can see I’ve loaded msn.com into the webview window.

When I capture the page, I get this image. The dimensions of the image file are twice that of the webview but as you can see only a quarter of the page is captured (half the width and half the height).

The capture code is pretty simple:

    webview.capturePage(function(img) {
        let jpgFile = img.toJPEG(90);
        jetpack.writeAsync(fullPath, jpgFile)
        .then(function() {
            // some other application code after saving

Note that I have tried scaling the native image array buffer and while that does resize the image as expected, it does not of course change the data that was captured. I have also tried specifying the rectangle passed to webivew.capturePage but that doesn’t do anything. Increasing it (say, width and height times the scale factor) simply returns an empty buffer.

Am I doing something wrong here? Is this a bug in the capturePage code? If so, is there a workaround?


A little more information on this.

I went back and redid some testing from the very beginning. If I pass a rect to the capturePage method that is scaled by the device scale factor, I get back an image that contains the full image data, but is scaled by the scale factor twice in size.

For example, my webview is 524 pixels wide (as returned by getting the dimensions of body.innerHTML).

If I call webview.capturePage without specifying a capture rectangle, I get back an image that is 1048 pixels (scale factor * width) wide but only contains the first half of the image.

If I call webview.capturePage but specify a capture rectangle with a width of scale factor * width, I get back an image with the full image but is 2096 pixels wide (scale factor * scale factor * width).

In both cases, there appears to be up scaling artifacts (pixelation) in the resulting images. Subsequently resizing down can get me an image with the expected data in the expected size but with significant degredation in quality.

At this point, I believe there is a bug somewhere in the capturePage code that is incorrectly applying the scaling factor twice.