Below is my html code, and it gets the error: "Failed to execute 'putImageData' on 'CanvasRenderingContext2D': parameter 1 is not of type 'ImageData'."
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<canvas id="c"></canvas>
<script>
const data = new Uint8ClampedArray([255, 0, 0, 1]);
const ctx = document.querySelector("#c").getContext("2d");
ctx.putImageData(data, 0, 0);
</script>
</body>
</html>
Below is my html code, and it gets the error: "Failed to execute 'putImageData' on 'CanvasRenderingContext2D': parameter 1 is not of type 'ImageData'."
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<canvas id="c"></canvas>
<script>
const data = new Uint8ClampedArray([255, 0, 0, 1]);
const ctx = document.querySelector("#c").getContext("2d");
ctx.putImageData(data, 0, 0);
</script>
</body>
</html>
Share
Improve this question
asked Aug 21, 2019 at 8:20
westfallwestfall
3831 gold badge3 silver badges8 bronze badges
2
-
1
I looks like you missing something. try wrapping your Uint8ClampedArray with an imageData object as such:
const myimg = new ImageData(data, 100, 50)
(the 100 represents the width of the canvas, 50 is height) and now you should have a real imageData stream (unlike Uint8ClampedArray which is a binary array and NOT and imageData object) – Max Svidlo Commented Aug 21, 2019 at 8:36 - @Max Svid yes, thank you! – westfall Commented Aug 22, 2019 at 2:03
2 Answers
Reset to default 2You have 1 main problem in your code, and 1 extra small problem in your code.
Main problem
.putImageData
requires ImageData
as its first argument. Instead, you gave a Uint8ClampedArray
.
To solve this, you need to create an ImageData
instance with the Uint8ClampedArray
:
data = new ImageData(new Uint8ClampedArray([255, 0, 0, 1]), /* other required params */);
Extra problem
In your Uint8ClampedArray
, you have an array [255, 0, 0, 1]
. This data actually converts to rgba(255, 0, 0, 0.005)
. In other words, your little red box will be rendered with alpha of 0.005, almost transparent.
To make it opaque, you need to convert the alpha into scale of 255.
For example, if you want a 1x1 opaque red box, you need to give [255, 0, 0, 255]
to the Uint8ClampedArray
.
Example
See below example of a 2x2 half transparent (alpha of 0.5) red box.
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');
const data = new Uint8ClampedArray([
255, 0, 0, 128,
255, 0, 0, 128,
255, 0, 0, 128,
255, 0, 0, 128
]);
const imageData = new ImageData(data, 2, 2);
ctx.putImageData(imageData, 0, 0);
<canvas id="canvas"></canvas>
As the error message says, putImageData() expects an ImageData object like:
const canvas = document.querySelector("#c");
const ctx = canvas.getContext("2d");
const imageData = ctx.createImageData(canvas.width, canvas.height);
for (let i = 0; i < imageData.data.length; i += 4) {
imageData.data[i + 0] =
imageData.data[i + 1] =
imageData.data[i + 2] = (i % canvas.width) % 256;
imageData.data[i + 3] = 255; // A value
}
ctx.putImageData(imageData, 0, 0);
<canvas id="c" width="500" height="300"></canvas>