画布形状顶部的画布图像数据不透明度

问题描述:

在下面的示例中,我将每个图像像素的不透明度设置为零.为什么看不到灰色背景矩形,我该如何实现?在形状与图像数据的渲染过程中是否缺少某些东西?

In the following example I've set the opacity of every image pixel to zero. Why isn't the grey background rectangle visible and how can I achieve that? Am I missing something in the rendering process of the shape vs image data?

<!DOCTYPE html>
<meta charset="utf-8">

<script src="https://d3js.org/d3.v4.min.js"></script>

<body>
    <canvas id='myCanvas'></canvas>
</body>

<script type="text/javascript">

    var width = 500;
    var height = 500;

    var canvas = document.getElementById('myCanvas')
    context = canvas.getContext("2d"),

    canvas.width = width;
    canvas.height = height;

    context.fillStyle = "grey";
    context.fillRect(0,0,100,100);

    var imageData = context.createImageData(width, height);

    for (var i = 0, l = 0; i<height; ++i) {
        for (j = 0; j<width; ++j, l += 4) {
            imageData.data[l+0] = Math.round( Math.random() * 255);
            imageData.data[l+1] = Math.round( Math.random() * 255);
            imageData.data[l+2] = Math.round( Math.random() * 255);
            imageData.data[l+3] = 0;
        }

    }

    context.putImageData(imageData, 0, 0);

</script>

putImageData 将使用您在ImageData中传递的像素设置上下文中的像素.

putImageData will set the pixels on your context with the ones you passed in the ImageData.

如果在ImageData中将给定像素设置为透明,则放置后它也会出现在上下文中.

If a given pixel is set to transparent in the ImageData, so will it be on the context after you put it.

为避免这种情况,可以使用ImageBitmap对象,该对象可以像图像一样在上下文中进行绘制,

To avoid this, you can use an ImageBitmap object, that you'll be able to draw on your context like an image,

const ctx = c.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(0,0,30,30);
const iData = ctx.createImageData(300, 150);
// make the noise mostly transparent
iData.data.forEach((d,i,a)=>{
  a[i] = (i+1)%4 ? Math.random() * 255 : Math.random() * 125;
  })
createImageBitmap(iData).then(img => ctx.drawImage(img, 0,0));

<canvas id="c"></canvas>

或使用屏幕外的画布:

const ctx = c.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(0,0,30,30);
const iData = ctx.createImageData(300, 150);
// make the noise mostly transparent
iData.data.forEach((d,i,a)=>{
  a[i] = (i+1)%4 ? Math.random() * 255 : Math.random() * 125;
  })

const offCtx = c.cloneNode().getContext('2d'); // an offscreen canvas
offCtx.putImageData(iData, 0,0);
ctx.drawImage(offCtx.canvas, 0,0);

<canvas id="c"></canvas>