我目前正在使用画布使用 JavaScript 创建屏幕截图并将它们编码为 base64。
但是,我目前的截图只包括实际的网页,没有其他内容(没有地址栏等),我想知道是否可以实现全屏截图(任务栏和整个浏览器窗口,等)以编程方式。
我目前正在使用画布使用 JavaScript 创建屏幕截图并将它们编码为 base64。
但是,我目前的截图只包括实际的网页,没有其他内容(没有地址栏等),我想知道是否可以实现全屏截图(任务栏和整个浏览器窗口,等)以编程方式。
Firefox 没有此功能。您可以做的最好的事情是通过js-ctypes使用操作系统功能。然而,这并不简单。无论如何,我需要 Windows API 的这段代码,所以它来了。首先,您需要设置库、函数和数据类型:
Components.utils.import("resource://gre/modules/ctypes.jsm");
var userlib = ctypes.open("user32");
var gdilib = ctypes.open("gdi32");
var HWND = ctypes.voidptr_t;
var HGDIOBJ = ctypes.voidptr_t;
var HDC = HGDIOBJ;
var HBITMAP = HGDIOBJ;
var LPCTSTR = ctypes.unsigned_char.ptr;
var WORD = ctypes.uint16_t;
var DWORD = ctypes.uint32_t;
var SRCCOPY = 0xCC0020;
var BITMAPCOREHEADER = ctypes.StructType("BITMAPCOREHEADER", [
{bcSize: DWORD},
{bcWidth: WORD},
{bcHeight: WORD},
{bcPlanes: WORD},
{bcBitCount: WORD}
]);
var GetDC = userlib.declare(
"GetDC", ctypes.winapi_abi,
HDC,
HWND
);
var ReleaseDC = userlib.declare(
"ReleaseDC", ctypes.winapi_abi,
ctypes.int,
HWND, HDC
);
var CreateCompatibleDC = gdilib.declare(
"CreateCompatibleDC", ctypes.winapi_abi,
HDC,
HDC
);
var CreateCompatibleBitmap = gdilib.declare(
"CreateCompatibleBitmap", ctypes.winapi_abi,
HBITMAP,
HDC, ctypes.int, ctypes.int
);
var DeleteObject = gdilib.declare(
"DeleteObject", ctypes.winapi_abi,
ctypes.bool,
HGDIOBJ
);
var SelectObject = gdilib.declare(
"SelectObject", ctypes.winapi_abi,
HGDIOBJ,
HDC, HGDIOBJ
);
var BitBlt = gdilib.declare(
"BitBlt", ctypes.winapi_abi,
ctypes.bool,
HDC, ctypes.int, ctypes.int, ctypes.int, ctypes.int,
HDC, ctypes.int, ctypes.int, DWORD
);
var GetDIBits = gdilib.declare(
"GetDIBits", ctypes.winapi_abi,
ctypes.int,
HDC, HBITMAP, ctypes.unsigned_int, ctypes.unsigned_int,
ctypes.unsigned_char.ptr, BITMAPCOREHEADER.ptr, ctypes.unsigned_int
);
现在有趣的部分:
// The screen part we want to copy
var x = 0;
var y = 0;
var width = screen.width;
var height = screen.height;
// Create a bitmap/device context for the data
var screenDC = GetDC(null);
var dc = CreateCompatibleDC(screenDC);
var bitmap = CreateCompatibleBitmap(screenDC, width, height);
// Copy screen contents to bitmap
SelectObject(dc, bitmap);
BitBlt(dc, 0, 0, width, height, screenDC, x, y, SRCCOPY);
// Extract bitmap data
var bitmapHeader = new BITMAPCOREHEADER();
bitmapHeader.bcSize = BITMAPCOREHEADER.size;
bitmapHeader.bcWidth = width;
bitmapHeader.bcHeight = height;
bitmapHeader.bcPlanes = 1;
bitmapHeader.bcBitCount = 32;
var dataSize = width * height * 4;
var buffer = new ctypes.ArrayType(ctypes.unsigned_char, dataSize)();
GetDIBits(dc, bitmap, 0, height, buffer, bitmapHeader.address(), 0);
// Clean up
ReleaseDC(null, screenDC);
DeleteObject(dc);
DeleteObject(bitmap);
userlib.close();
gdilib.close();
// Draw data to the canvas
var canvas = document.getElementById("canvas");
canvas.setAttribute("width", width);
canvas.setAttribute("height", height);
var context = canvas.getContext("2d");
var imageData = context.createImageData(width, height);
for (var i = 0; i < height; i++)
{
// Windows bitmaps are stored bottom-to-top, they are also using BGR0
// byte order instead of RGBA. The data needs to be corrected here.
var offset1 = i * width * 4;
var offset2 = (height - 1 - i) * width * 4;
for (var j = 0; j < width; j++)
{
imageData.data[offset1 + j * 4 + 0] = buffer[offset2 + j * 4 + 2];
imageData.data[offset1 + j * 4 + 1] = buffer[offset2 + j * 4 + 1];
imageData.data[offset1 + j * 4 + 2] = buffer[offset2 + j * 4 + 0];
imageData.data[offset1 + j * 4 + 3] = 255;
}
}
context.putImageData(imageData, 0, 0);
对于其他操作系统,您当然需要完全不同的代码。另一种方法是用你的扩展打包一个专门的 DLL 并通过 js-ctypes 使用它——这将允许用 C++ 编写相同的东西,这会稍微简单一些。
否 - 如评论所述的安全性。
您唯一能做的就是从文档信息(如 location.href)中获取您需要/可以获取的内容。将其作为可见信息添加到底部/顶部 => grap => 再次隐藏(如果用户应该继续工作)。
首先按下shift+F2
它打开Firefox控制台..给出命令screenshot --fullpage
并按Enter(对于整页)
screenshot
(仅适用于可见部分)
您也可以通过转到工具-> Web 开发人员-> 开发人员工具栏来执行此操作
值得一试..最好没有扩展