我有一个ImageData对象,它保存所有监视器的屏幕截图,因此它是一个巨大的ImageData。我现在想要每次绘制一个显示器。我有所有的显示器尺寸。
所以我正在尝试使用ctx.putImageData(myImgDat, topLeftMonX, topLeftMonY, monWidth, monHeight)
,但它不起作用,我不认为我在文档中看到的那么肮脏的概念:https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/putImageData#Understanding_putImageData
是否可以将部分imgaedata绘制到画布上?
答案 0 :(得分:2)
是的,它是可能的,它不会对您的代码起作用,因为您的传递不符合函数的格式。
正如MDN CanvasRenderingContext2D.putImageData()所述,它接受3
或7
个参数,您必须传递3
或7
,否则,在您的示例中,{ {1}}和monWidth
将用作monHeight
和dirtyX
,而不是dirtyY
和dirtyWidth
。您的代码可能会执行
dirtyHeighy
。rect(monWidth, monHeight, IMAGEDATA_WIDTH, IMAGEDATA_HEIGHT)
。所以,以某种方式将目标区域放到目标画布的rect(topLeftMonX + monWidth, topLeftMonY + monHeight, IMAGEDATA_WIDTH, IMAGEDATA_HEIGHT)
上并不是很直接,要达到你的条件,你可能需要这样做:
(0,0)
移至目标画布(0,0)
。(-topLeftMonX,
-topLeftMonY)
,它现在位于画布的(topLeftMonX, topLeftMonY)
位置。 (0, 0)
。topLeftMonX x topLeftMonY
上面的代码会将ctx.putImageData(myImgDat,-topLeftMonX, -topLeftMonY, topLeftMonX, topLeftMonY, monWidth, monHeight);
上的rect(topLeftMonX, topLeftMonY, monWidth, monHeight)
复制到:myImgDat
在画布上。
您可以从下面的代码段了解它的工作原理。
rect(0, 0, monWidth, monHeight)

var canvas = document.getElementById('bigCanvas')
,ctx = canvas.getContext('2d');
var tcanvas = document.getElementById('testCanvas')
,tctx = tcanvas.getContext('2d');
var grd = tctx.createRadialGradient(150, 100, 10, 150, 110, 150);
grd.addColorStop(0, "black");
grd.addColorStop(0.15, "blue");
grd.addColorStop(0.3, "cyan");
grd.addColorStop(0.5, "green");
grd.addColorStop(0.7, "yellow");
grd.addColorStop(0.85, "orange");
grd.addColorStop(1, "red");
tctx.fillStyle = grd;
tctx.fillRect(0, 0, 300, 200);
var imageData = tctx.getImageData(0, 0, 300, 200);
// Move imagedata's origin to (-150, -100) on canvas,
// start to put data on canvas at imgae data's (150, 100) and size is 150x100
// => copy rect(150, 100, 150, 100) to canvas' s rect (0, 0, 150, 100)
ctx.putImageData(imageData, -150, -100, 150, 100, 150, 100);
// Move imagedata's origin to (150, 100) on canvas,
//start to put data on canvas at imgae data's (0, 0) and and size is 150x100
// => copy rect(0, 0, 150, 100) to canvas' s rect (150, 100, 150, 100)
ctx.putImageData(imageData, 150, 100, 0, 0, 150, 100);
// Move imagedata's origin to (150, -100) on canvas,
// start to put data on canvas at imgae data's (0, 100) and size is 150x100
// => copy rect(0, 100, 150, 100) to canvas' s rect (150, 0, 150, 100)
ctx.putImageData(imageData, 150, -100, 0, 100, 150, 100);
// Move imagedata's origin to (-150, 100) on canvas,
// start to put data on canvas at imgae data's (200, 0) and size is 100x100
// => copy rect(200, 0, 150, 100) to canvas' s rect (50, 100, 150, 100)
ctx.putImageData(imageData, -150, 100, 200, 0, 100, 100);

答案 1 :(得分:0)
这是另一种解决方案:
var iref = imagedata.data;
// start - because took a single screenshot of alllll put togather, lets portion out the imagedata
console.time('portion out image data');
for (var i=0; i<collMonInfos.length; i++) {
var screenUseW = collMonInfos[i].w;
var screenUseH = collMonInfos[i].h;
var screnImagedata = new ImageData(screenUseW, screenUseH);
var siref = screnImagedata.data;
var si = 0;
for (var y=collMonInfos[i].y; y<collMonInfos[i].y+screenUseH; y++) {
for (var x=collMonInfos[i].x; x<collMonInfos[i].x+screenUseW; x++) {
var pix1 = (fullWidth*y*4) + (x * 4);
var B = iref[pix1];
siref[si] = iref[pix1+2];
siref[si+1] = iref[pix1+1];
siref[si+2] = B;
siref[si+3] = 255;
si += 4;
}
}
collMonInfos[i].screenshot = screnImagedata;
}
console.timeEnd('portion out image data');