在 HTML5 画布上下文上使用 putImageData 时“重载解析失败”

问题描述 投票:0回答:1

我正在阅读 MDN 画布教程,并编写了这段代码,该代码应该将此画布的左上角(50x50 像素)涂成红色。

我遇到了一个奇怪的错误(

Overload resolution failed
),在谷歌搜索时我找不到任何东西。

Test002.html:35 Uncaught TypeError: Failed to execute 'putImageData' on 'CanvasRenderingContext2D': Overload resolution failed.
    at draw (Test002.html:35:8)
draw @ Test002.html:35
load (async)
(anonymous) @ Test002.html:48
    

我正在 Chrome 中对此进行测试。不确定我做错了什么......有什么想法吗?

<html>
    <body>
        <canvas id="canvas1" width="800" height="600" style="border: 1px solid black;">

    <script type="text/javascript">

        const canvas = document.getElementById("canvas1");
        const ctx = canvas.getContext("2d");

        const idata = ctx.getImageData(0, 0, canvas.width, canvas.height);
        console.log(idata);


        const getColorIndicesForCoord = (x, y, width) => {
          const red = y * (width * 4) + x * 4;
          return [red, red + 1, red + 2, red + 3];
        };

        const colorIndices = getColorIndicesForCoord(5, 5, canvas.width);

        const [redIndex, greenIndex, blueIndex, alphaIndex] = colorIndices;

        function draw() {

            console.log("Started drawing.");

            for (let i=0; i<50; i++) {
                for (let j=0; j<50; j++) {
                    putPixel(i, j, 200, 0, 0);
                }
            }

            // (imageData, xLoc, yLoc, 0, 0, imgWidth, imgHeight); 

            ctx.putImageData(idata, 0, 0, 0, 0);

            console.log("Finished drawing.");
        }

        function putPixel(x,y,r,g,b) {
            let colorIndices = getColorIndicesForCoord(x, y, canvas.width);
            idata[colorIndices[0]] = r;
            idata[colorIndices[1]] = g;
            idata[colorIndices[2]] = b;
            // idata[colorIndices[3]] = a;
        }

        window.addEventListener("load", draw);

    </script>
    </body>

</html>

javascript html5-canvas
1个回答
2
投票

FF中的错误更加清晰:

Uncaught TypeError: CanvasRenderingContext2D.putImageData:
5 is not a valid argument count for any overload.

请参阅 MDN 了解正确的重载:

putImageData(imageData, dx, dy)
putImageData(imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)

您可以使用 3 个或 7 个参数,但您给出了 5 个。

我还建议尽量减少问题——你可以用几行代码重现这个问题——创建一个画布,创建一个上下文并使用 5 个参数调用

.putImageData()

const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
ctx.putImageData(imageData, 0, 0, 0, 0);

修复:

const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
ctx.putImageData(imageData, 0, 0, 0, 0, canvas.width, canvas.height);
// or ctx.putImageData(imageData, 0, 0);

除此之外,您的

putPixel
功能不正确。它在
idata
对象上设置属性,而不是
idata.data
,这是实际图像数据缓冲区所在的位置。另外,alpha 应为 255 以确保颜色不透明。

function putPixel(x, y, r, g, b) {
    const colorIndices = getColorIndicesForCoord(x, y, canvas.width);
    idata.data[colorIndices[0]] = r;
    idata.data[colorIndices[1]] = g;
    idata.data[colorIndices[2]] = b;
    idata.data[colorIndices[3]] = 255;
}

也就是说,这里的设计还有一些不足之处。为

getColorIndicesForCoord
分配一个新数组非常昂贵,因此您可能希望将坐标一一转换为线性数组,并避免每帧数千次分配。当然,避免过早优化是件好事,但在代码运行之前避免抽象也很好——然后会更清楚如何分解函数,最好是那些不会在其范围之外改变状态的函数。

© www.soinside.com 2019 - 2024. All rights reserved.