In one of my applications, I am reading picture on the canvas as ImageData.
Sample code is
<!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>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var imgData = ctx.createImageData(100, 100);
var i;
for (i = 0; i < imgData.data.length; i += 4) {
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>
<p><strong>Note:</strong> The canvas tag is not supported in Internet
Explorer 8 and earlier versions.</p>
</body>
</html>
I am passing same ImageData to various other APIs and these other APIs need unique id for each ImageData to differentiate. So, I simply modified code as shown below :
<!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>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var imgData = ctx.createImageData(100, 100);
var i;
for (i = 0; i < imgData.data.length; i += 4) {
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);
imgData.id = 21323;
alert("imgData.id --"+imgData.id);
imgData.picType = "Rect";
alert("imgData.picType --"+imgData.picType);
</script>
<p><strong>Note:</strong> The canvas tag is not supported in Internet
Explorer 8 and earlier versions.</p>
</body>
</html>
I am curious to know how it worked - addition of some properties to ImageData?
Like everything else in javascript ImageData too is an object and as you might be aware adding new properties to objects in JS is a matter of obj1.prop1 = val1
Now you might ask why adding some random value to your ImageData didn't corrupt your image ? The answer is simple : byte representation of image is stored in data property of ImageData as a Uint8ClampedArray .
Console dump of imageData
Related
So I am very new to programming at all and it might seem obvious to you, but I can't figure out why the following code won't work (the first three lines of the script are nescessary for another part of the full Webpage, but I don't see why that would hinder the rest of the code working) :
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
<script>
document.getElementById("demo2").innerHTML = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
document.getElementById("demo2").style.background = "red";
document.getElementsById("demo2").style.fontSize = "190%";
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10,10,150,80);
</script>
</body>
</html>
It works fine.
I removed the first 3 lines of code because the element dont exist and that crashes your JS
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10,10,150,80);
</script>
</body>
</html>
As you said earlier the first three lines of your code is hinder working the rest of your codes.
So why it is happening?
The javascript is a single-threaded language so it will go into your code line by line
1| document.getElementById("demo2").innerHTML = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
2| document.getElementById("demo2").style.background = "red";
3| document.getElementsById("demo2").style.fontSize = "190%";
...
So whenever you got this it will run the first line then the second, then the rest line by line. Due to this feature whenever one of your lines throw and error the rest functionality will be stopped.
What we can do in your case then?
Since you got the same script for multiple pages, then you should consider which part of code you want to run (actually which part is runnable).
There are several ways to do this:
Make conditions on your scripts
In this approach you should define a set of condition to check whether the elements exist in the page or not, so your code should be something like this:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
<script>
var demo2 = document.getElementById("demo2");
if (demo2) {
demo2.innerHTML = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
demo2.style.background = "red";
demo2.style.fontSize = "190%";
}
var c = document.getElementById("myCanvas");
if (c) {
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 80);
}
</script>
</body>
</html>
Make your code modular
In order to run each specific part of code you can create two different modules, so let's assume the first one is:
// demo2.js
document.getElementById("demo2").innerHTML = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
document.getElementById("demo2").style.background = "red";
document.getElementsById("demo2").style.fontSize = "190%";
and the second part is:
// canvas.js
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 80);
and this is the page that you using demo2:
<!DOCTYPE html>
<html>
<body>
<div id='demo2'>
...
</div>
<script src="./demo2.js"></script> // I just assuemed they both are in same directory
</body>
</html>
and this is the page that you using canvas:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
<script src="./canvas.js"></script> // I just assuemed they both are in same directory
</body>
</html>
Create empty div's with display: none; in each page in order to prevent error (not preferable at all)
This approach is not preferred at all because you will add a useless element to your DOM and only make your DOM bigger for no reason.
<!DOCTYPE html>
<html>
<body>
<div style="display: none;" id="demo2"></div>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
<script>
var demo2 = document.getElementById("demo2");
demo2.innerHTML = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
demo2.style.background = "red";
demo2.style.fontSize = "190%";
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 80);
</script>
</body>
</html>
I assume you want something like this:
const setup = () => {
const demo2 = document.getElementById("demo2");
if(demo2 !== null) {
demo2.textContent = "Text und Hintergrund per Java erstellt, font-size ist hier fontSize";
demo2.style.background = "red";
demo2.style.fontSize = "190%";
}
const c = document.getElementById("myCanvas");
if(c !== null) {
let ctx = c.getContext("2d");
// Create gradient
let grd = ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10,10,150,80);
}
}
//load
window.addEventListener('load', setup);
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
</body>
</html>
I'm drawing an image on my canvas and trying to use getImageData() from canvas to get the image data but I got all 0's in return. From my understanding, the image hasn't finished a load so I get the 0's. From this issue: getImageData always returning 0 seems like I need to wait by using onload. Is there another way to get the data by not use onload function? I want to declare an image tag in my html. Here is my code:
<html>
<head>
</head>
<body>
<script>
var bgMap = {
"bg1": "image1.JPG",
"bg2": "image2.JPG"
}
</script>
<center>
<select id="selectBg" onchange="document.getElementById('bgImage').src = bgMap[this.value]">
<option value="bg1">Bg1</option>
<option value="bg2">Bg2</option>
</select>
</center>
<img id='bgImage' src='image1.JPG' width=500 height=500 />
<canvas id='bgCanvas'></canvas>
<script>
var canvas = document.getElementById('bgCanvas')
var bgImage = document.getElementById('bgImage')
canvas.width = 500
canvas.height = 500
var ctx = canvas.getContext("2d")
ctx.drawImage(bgImage, 0, 0, 500, 500)
var imageData = ctx.getImageData(0, 0, 500, 500)
var rgba = imageData.data;
for (var px = 0, ct = 500 * 500 * 4; px < ct; px += 4) {
var r = rgba[px];
var g = rgba[px + 1];
var b = rgba[px + 2];
var a = rgba[px + 3];
console.log(r,g,b,a)
}
console.log(rgba)
</script>
</body>
</html>
I have a problem t read the pixel's RGBA data from a image.But I am facing that all RGBA data( all 4 bytes for all pixel ) zero value.
i use this code for JavaScript :
By the way I use this code for html.
and tehn I run html by Chrome or Firefox but When I see the console log the all value of pixel Data is Zero.Why?
var canvas= document.getElementById('mycanvas');
var c=canvas.getContext("2d");
// c.beginPath();
// c.moveTo(0,0);
// c.lineTo(500,200);
// c.stroke();
var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
img.crossOrigin = "Anonymous";
// var img= document.getElementById('image')
img.onload=function () {
c.drawImage(img,0,0);
}
var myImageData = c.getImageData(0, 0, 500, 500);
//var myImageData = c.createImageData(600, 600);
var numBytes = myImageData.data.length;
var pixelData=myImageData.data;
console.log (numBytes);
console.log (pixelData);
// var x= function () {
// for(var i=0;i<pixelData.length;i+=40)
// {
// pixelData[i] = 255 - pixelData[i]; // red
// pixelData[i + 1] = 255 - pixelData[i + 1]; // green
// pixelData[i + 2] = 255 - pixelData[i + 2]; // blue
// }
// c.putImageData(myImageData, 0, 0);
// };
// //if (pixelData[i]&&pixelData[i+1]&&pixelData[i+2]===255) {
// //console.log (numBytes);
// //}
// //else {}
// //};
// //
// x();
//pixel = imageData.data[((row * (imageData.width * 4)) + (colume * 4)) + colorindex];
//var img = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); // here is the most important part because if you dont replace you will get a DOM 18 exception.
//window.location.href=image;
<!DOCTYPE html>
<html>
<head>
<title>Image processing</title>
<style type="text/css">
</style>
</head>
<body>
<canvas id="mycanvas" width="300" height="227">
</canvas>
<img src="https://mdn.mozillademos.org/files/5397/rhino.jpg" id="image" style="display:none;">
</style>
</style>="">
<script src="img.js">
</script>
</body>
</html>
This won't work as the image comes from another domain. The canvas accepts only images from the same origin. You cannot and should not be using getImageData() from external sources that don't support CORS.
But you can convert the image into dataURL and then paint the canvas.
Edit: Sorry for not expressing it properly. The only way would be to locally download the image to your server/domain and then draw it on the canvas.
I solved my problme.
firstly as Mohanesh Said we need use Localhost or http domain.So I installed the Python and used this command to creat localhost erver.
Python -m http.server
Second I used the creatpattern command instead drawimage.this code works for me:
var canvas = document.getElementById('mycanvas')
var c = canvas.getContext('2d');
// canvas.height = window.innerHeight;
// canvas.width = window.innerWidth;
var img = document.getElementById("image")
img.crossOrigin = "Anonymous";
var ptrn = c.createPattern(img, 'no-repeat');
c.fillStyle = ptrn;
c.fillRect(0, 0, canvas.width, canvas.height);
var myImageData = c.getImageData(0, 0, canvas.width, canvas.height);
var numBytes = myImageData.data.length;
var pixelData = myImageData.data;
console.log(numBytes);
console.log(pixelData);
<!DOCTYPE html>
<html>
<head>
<title>Image processing</title>
<style type="text/css">
</style>
</head>
<body>
<canvas id="mycanvas" width="100" height="100">
</canvas>
<img src="test1.png" alt="" id="image" style="display: none;" />
<script src="img22.js">
</script>
</body>
</html>
I am generating the image from the entered text in the text box. I need to get the pixel from the generated image. Right now I am doing the following
tCtx.fillText(entered_text, 20, 40);
imageElem.src = tCtx.canvas.toDataURL("image/png");
var imageData = tCtx.getImageData(0, 0, tCtx.canvas.width, tCtx.canvas.height);
var px = imageData.data;
var len = px.length;
for (var i = 0; i < len; i+=4) {
var redPx = px[i];
var greenPx = px[i+1];
var bluePx = px[i+2];
var alphaPx = px[i+3];
console.log(redPx,greenPx,bluePx);
}
Here the console prints the all 0's only for each pixel. But in the Canvas I am seeing the image, when I gave that toDataURL(), in image tag also I am seeing the Image. Don't know how.
When I use the custom images other than the text, then I am getting the pixel data like,
34 45 255 255
54 56 210 255 ...
You need to print Alpha channel to console as well. I also received 0,0,0 for all pixels. Since default canvas's background is (0,0,0,0) which is transparent. And black font is (0,0,0,noneZeroValue): (could be not 255 because of antialising). If you won't print alpha channel all of them will be 0,0,0.
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="100" height="20" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
window.onload = function() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
//ctx.font = "48px serif";
ctx.fillText("A lot of text", 0, 10);
//ctx.drawImage(ocanvas,0,0,c.width,c.height);
var imageData = ctx.getImageData(0, 0, c.width, c.height);
var px = imageData.data;
var len = px.length;
for (var i = 0; i < len; i+=4) {
var redPx = px[i];
var greenPx = px[i+1];
var bluePx = px[i+2];
var alphaPx = px[i+3];
//if (redPx!=0 || greenPx!=0 ||bluePx!=0 || alphaPx!=0){
console.log(redPx,greenPx,bluePx,alphaPx);
}
};
</script>
</body>
</html>
I found the solution.
What i did right now is
tCtx.putImageData(imageData, 0, 0, 0, 0, imageData.width, imageData.height);
because of this I am displaying the image out side of the canvas. So, it is not visible. Then I changed it to
tCtx.putImageData(imageData, 0, 0);
now, it is fine. Able to get the pixel data
I've a function that permits me to change the color of a PNG image:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<img id="testImage" width="400px" height="400px" style="display: none;" src='test.png'/>
<canvas id="canvas" width="400" height="400"></canvas>
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
image = document.getElementById("testImage");
ctx.drawImage(image,0,0);
var imgd = ctx.getImageData(0, 0, image.width, image.height),
pix = imgd.data,
uniqueColor = [255,255,127]; //Rossastro
// Loop lungo tutti i pixel per modificare i colori
for (var i = 0, n = pix.length; i <n; i += 4) {
pix[i] = uniqueColor[0]; // Componente Rossa
pix[i+1] = uniqueColor[1]; // Componente Blu
pix[i+2] = uniqueColor[2]; // Componente Verde
//pix[i+3] Trasparenza
}
ctx.putImageData(imgd, 0, 0);
All this code works perfectly on Mozilla Firefox, Internet Explorer 11, Microsoft Edge, but it doesn't work on Chrome and I don't know why.
If I make a breakpoint to the first line of the script and then I press the resume button in the debugger, all works great.
You are not waiting for the image to be loaded. You need to either listen to the load event on the image or the load event of the document, than fire your canvas code.
document.getElementById("testImage").addEventListener("load", function () { /* init canvas code */ } );