簡體   English   中英

JavaScript將圖像數據放在畫布上

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM