3

現在、キャンバスを使用して JavaScript でスクリーンショットを作成し、base64 でエンコードしています。

ただし、現在のスクリーンショットには実際の Web ページのみが含まれており (アドレスバーなどは含まれていません)、画面全体 (タスクバー、およびブラウザーウィンドウ全体) のスクリーンショットを取得できるかどうかを知りたいです。など) プログラムで。

4

3 に答える 3

4

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++ で記述できるようになり、少し簡単になります。

于 2012-04-18T17:01:54.713 に答える
0

いいえ - コメントで述べられているようなセキュリティ。

あなたができる唯一のことは、ドキュメント情報 (location.href など) から必要な/取得できるものを取得することです。それを、bottom/top => grap => hide again に表示される情報として追加します (ユーザーが作業を続行する必要がある場合)。

于 2012-04-18T13:28:07.177 に答える