Is there a possible way to create screenshots of t

2019-07-24 16:19发布

问题:

I'm currently creating screenshots with JavaScript using canvas and encoding them in base64.

However, my current screenshots only include the actual web page and nothing else (no address bar, etc.) and I'd like to know if it is possible to achieve a screenshot of the whole screen (taskbar, and the whole browser window, etc.) programmatically.

回答1:

Firefox doesn't have this functionality. The best you can do is using operating system functions via js-ctypes. However, it isn't quite simple. I needed this code for the Windows API anyway so here it comes. First you need to set up the libraries, functions and data types:

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
);

And now the interesting part:

// 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);

For other operating systems you would need entirely different code of course. The alternative would be packaging a specialized DLL with your extension and using it via js-ctypes - this would allow writing the same thing in C++, that would be slightly simpler.



回答2:

no - security like stated by the comments.

only thing you can do is to is to get what ever you need/can get from the document info (like location.href). Add that as visible information in bottom/top => grap => hide again (if user should continue working).



回答3:

first press shift+F2 it opens firefox console..give command screenshot --fullpage and press enter(For fullpage)

screenshot(For only the visible part)

you also can do this by going to tools->web developer->developer toolbar

Its worth take a try..its best without a extension