[英]JavaScript put Image data on top of canvas
我有以下代碼可以創建一個矩形,如下圖所示:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<p id='one'></p>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = 'black';
ctx.fillRect(20, 20, 40, 40)
var imgData = ctx.createImageData(100, 100);
var i;
for (i = 0; i < imgData.data.length; i += 16) {
imgData.data[i + 0] = 255;
imgData.data[i + 1] = 0;
imgData.data[i + 2] = 0;
imgData.data[i + 3] = 255;
}
// ctx.putImageData(imgData, 10, 10);
</script>
</body>
</html>
當我通過不注釋ctx.putImageData
來確保添加了圖像數據時,僅得到如下圖所示的圖像數據:
如何確保在紅線之間的白色空間中在黑色矩形的頂部創建圖像?
我希望能夠看到黑色矩形。 我嘗試更改Alpha通道,但沒有執行任何操作。
提前致謝 :)。
putImageData
會將目標像素替換為ImageData中包含的像素,無論它們是什么。
這意味着,如果您的ImageData包含透明像素,則一旦將ImageData放在畫布上,這些透明像素就會在那里。
有幾種方法可以完成您想要的。
需要較少代碼更改的一種是從上下文的當前狀態進行像素操作。 通過調用getImageData
而不是createImageData
,您將擁有一個ImageData,其中包含所選區域中當前繪制的像素。
var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); ctx.fillStyle = 'black'; ctx.fillRect(20, 20, 40, 40); // get the current pixels at (x, y, width, height) var imgData = ctx.getImageData(10, 10, 100, 100); var i; // and do the pixel manip over these pixels for (i = 0; i < imgData.data.length; i += 16) { imgData.data[i + 0] = 255; imgData.data[i + 1] = 0; imgData.data[i + 2] = 0; imgData.data[i + 3] = 255; } ctx.putImageData(imgData, 10, 10);
<canvas id="myCanvas"></canvas>
主要警告是,與createImageData
相比, getImageData
速度較慢並且需要更多的內存,因此,如果要在動畫的每一幀中都這樣做,則可能不合適。
在這種情況下(動畫)的另一種解決方案是使用第二個屏幕外畫布,您將在其上繪制一次ImageData,然后使用drawImage
在主畫布上繪制此屏幕外畫布。
var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); ctx.fillStyle = 'black'; var gridImage = generateGrid(100, 100); var x = 0; anim(); /* Makes your pixel manip on an off-screen canvas Returns the off-screen canvas */ function generateGrid(width, height){ var canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; var off_ctx = canvas.getContext('2d'); var imgData = off_ctx.createImageData(width, height); for (i = 0; i < imgData.data.length; i += 16) { imgData.data[i + 0] = 255; imgData.data[i + 1] = 0; imgData.data[i + 2] = 0; imgData.data[i + 3] = 255; } off_ctx.putImageData(imgData, 0,0); return canvas; } function anim(){ ctx.clearRect(0,0,c.width, c.height); x = (x + 1) % (c.width + 100); ctx.fillRect(x, 20, 40, 40); // and here you draw your generated canvas ctx.drawImage(gridImage, x - 10, 0); requestAnimationFrame(anim); }
<canvas id="myCanvas"></canvas>
您還可以重構代碼,以便在繪制完ImageData之后但在當前圖形之后繪制普通圖形(此處為fillRect
),這要歸功於上下文的globalCompositeOperation
屬性:
var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); // do first your pixel manip var imgData = ctx.createImageData(100, 100); var i; for (i = 0; i < imgData.data.length; i += 16) { imgData.data[i + 0] = 255; imgData.data[i + 1] = 0; imgData.data[i + 2] = 0; imgData.data[i + 3] = 255; } ctx.putImageData(imgData, 10, 10); // change the gCO to draw behind current non-transparent pixels ctx.globalCompositeOperation = 'destination-over'; // now make your normal drawings ctx.fillStyle = 'black'; ctx.fillRect(20, 20, 40, 40); // reset the gCO ctx.globalCompositeOperation = 'source-over';
<canvas id="myCanvas"></canvas>
最后,如果僅針對下一代瀏覽器 ,則可以使用ImageBitmap對象 ,該對象將以更少的代碼行產生與屏幕外畫布相同的結果:
(async () => { var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); ctx.fillStyle = 'black'; var gridImage = await generateGrid(100, 100); var x = 0; anim(); /* Makes your pixel manip on an empty ImageData Returns an Promise resolving to an ImageBitmap */ function generateGrid(width, height) { var imgData = ctx.createImageData(width, height); for (i = 0; i < imgData.data.length; i += 16) { imgData.data[i + 0] = 255; imgData.data[i + 1] = 0; imgData.data[i + 2] = 0; imgData.data[i + 3] = 255; } return createImageBitmap(imgData); } function anim() { ctx.clearRect(0, 0, c.width, c.height); x = (x + 1) % (c.width + 100); ctx.fillRect(x, 20, 40, 40); // and here you draw your generated canvas ctx.drawImage(gridImage, x - 10, 0); requestAnimationFrame(anim); } })();
<canvas id="myCanvas"></canvas>
我無法使其與您的確切代碼一起工作,但是當我嘗試重疊2張圖像時,我設法使其重疊。
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"> </canvas> <p id = 'one'></p> <script> var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); var img = ctx.createImageData(100, 100); var i; for (i = 0; i < img.data.length; i += 6) { img.data[i+0] = 255; img.data[i+1] = 0; img.data[i+2] = 0; img.data[i+3] = 255; } var img2 = ctx.createImageData(100, 100); var i; for (i = 0; i < img2.data.length; i += 20) { img2.data[i+0] = 0; img2.data[i+1] = 255; img2.data[i+2] = 0; img2.data[i+3] = 255; } var pixels = 4*100*100; var imgData1 = img.data; var imgData2 = img2.data; while (pixels--){ imgData1[pixels] = imgData1[pixels] * 0.5 + imgData2[pixels] *0.5; } img.data = imgData1; ctx.putImageData(img, 10, 0); </script>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.