I am looking for firefox addon api to take screenshot of visible area of document.
Chrome and Safari have api's to achieve this. And they are pretty fast. I could not find anything specific for firefox.
I found a workaround at How do I use the canvas drawWindow function in an addon created using the addon sdk? but this solution takes full page screenshot with scrolls including (hidden parts of document). There are 2 issues for this solution;
1- if page has long scroll, it takes long time to complete screenshot process. Because it is using canvas based drawing.
2- I would like to get screenshot of visible area of document, not whole document.
Is there any workaround for this?
Thanks.
To take a screenshot in Firefox using the Firefox Screenshots feature: Right-clickHold down the control key while you click on an empty part of the page and select Take Screenshot. Alternatively, use the keyboard shortcut Ctrl + Shift + S .
Sorry for the non-obvious change, but in Firefox 88, Firefox Screenshot stopped being a "Page Action" that you could access from the ••• menu in the address bar. It now has an optional toolbar button ("Browser Action") in addition to right-click context menu integration and the keyboard shortcut (Ctrl+Shift+S).
Once you have the Firefox browser up and running, click on the three-lined menu at the top right. Go to More tools, followed by the Customize Toolbar option. Find the Screenshot icon and move it to the toolbar. Once the icon is where you want it to be, go to the page where you want to take the scrolling screenshot.
Using the SDK you can do something like this:
const { window: { document } } = require('sdk/addon/window');
const { getTabContentWindow, getActiveTab } = require('sdk/tabs/utils');
const { getMostRecentBrowserWindow } = require('sdk/window/utils');
const canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
document.documentElement.appendChild(canvas);
function captureTab(tab=getActiveTab(getMostRecentBrowserWindow())) {
let contentWindow = getTabContentWindow(tab);
let w = contentWindow.innerWidth;
let h = contentWindow.innerHeight;
let x = contentWindow.scrollX;
let y = contentWindow.scrollY;
canvas.width = w;
canvas.height = h;
let ctx = canvas.getContext('2d');
ctx.drawWindow(contentWindow, x, y, w, h, '#000');
return canvas.toDataURL();
}
That should takes only the visible area. By default, it grabs the active tab, but you can pass any other tab – because is designed as low level API it takes a native tab, however, not a SDK tab.
You can put in a module and exports just the captureTab
function.
Edit: e10s version
The code above is not currently compatible with Firefox with e10s available, as Ian Bicking noted in the comment. An easy way to workaround this issue, is create a temporary canvas in the same document and content process we want to capture the screenshot:
const { getTabContentWindow, getActiveTab } = require('sdk/tabs/utils');
const { getMostRecentBrowserWindow } = require('sdk/window/utils');
function captureTab(tab=getActiveTab(getMostRecentBrowserWindow())) {
let contentWindow = getTabContentWindow(tab);
let { document } = contentWindow;
let w = contentWindow.innerWidth;
let h = contentWindow.innerHeight;
let x = contentWindow.scrollX;
let y = contentWindow.scrollY;
let canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
canvas.width = w;
canvas.height = h;
let ctx = canvas.getContext('2d');
ctx.drawWindow(contentWindow, x, y, w, h, '#000');
let dataURL = canvas.toDataURL();
canvas = null;
return dataURL;
}
That works in both e10s and no-e10s FF version; the downside comparing to the previous one is creating a canvas every time we want to take a screenshot, but I think is acceptable.
Your assumption that taking a screenshot on Firefox with canvas is somehow slow is wrong.
I did a couple of screenshots and Firefox/canvas was faster than Chrome/captureVisibleTab.
Actually Firefox is better suited for as-fast-as-possible screenshots, since its canvas expose to privileged code the mozFetchAsStream
method, allowing to bypass the actual bottleneck which is the base64 encoding of the image data.
Some numbers
captureVisibleTab
200-205msdrawImage
20-25ms + toDataURL
125-130msThe devtools screenshot
command is a good example of how to capture just the visible part
In all fairness, to make a meaningful comparison one has to take into account whether Chrome's PNG encoder favors compression over speed. Still, this doesn't change the fact that Firefox's canvas is fine.
edit: OK, that base64 encoding remark is dumb, I don't know what I was thinking. Perhaps what I should write instead is that Firefox's canvas is not only fast but also versatile.
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