Reading pixel data by JavaScript thought Canvas - javascript

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>

Related

javascript fixing canvas tainted in MDN example

I am working my way through MDN Canvas tutorial.
Working well until I get to Pixel manipulation, a color picker example.
getImageData gives:
MDNTutorialBaseppp.html:21 Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
at HTMLCanvasElement.pick
Here's the code I'm running:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<canvas id="canvas" width="600" height="300"></canvas>
<script>
var img = new Image();
//img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
img.src = 'photo2.jpg';
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
img.onload = function() {
ctx.drawImage(img, 0, 0);
img.style.display = 'none';
};
var color = document.getElementById('color');
function pick(event) {
var x = event.layerX;
var y = event.layerY;
var pixel = ctx.getImageData(x, y, 1, 1);
var data = pixel.data;
var rgba = 'rgba(' + data[0] + ', ' + data[1] +
', ' + data[2] + ', ' + (data[3] / 255) + ')';
color.style.background = rgba;
color.textContent = rgba;
}
canvas.addEventListener('mousemove', pick);
</script>
</body>
</html>
Been beating on for several hours over several.
Can anyone spot the error of my ways.
The comments on this question provide an approach to working through this issue for the particular case presented. You need to be running a local server which is easy to do. The underlying issue is a complicated topic that I don't pretend to fully understand.

Get all 0's in return after use getImageData()

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>

How to add new properties to HTML ImageData?

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

javascript not linking correctly with HTML. how to fix?

here's my HTML
<html>
<head>
<meta charset="UTF-8" />
<script src="script.js"></script>
</head>
....
and here's the javascript. everything was fine when i had the script inline, but when i move it outside of the html file it breaks. just a simple html canvas drawing but not sure the issue. ideas?
// Canvas 1
var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
photo = document.getElementById("red");
function drawImage() {
context.drawImage(photo, 0, 0);
}
window.addEventListener("load", drawImage, false);
// Canvas 2
var canvas2 = document.getElementById("canvas2");
var context2 = canvas2.getContext("2d");
context2.fillStyle = "darkRed";
context2.fillRect(0, 2, 800, 500);
context2.moveTo(0, 0);
context2.lineTo(400, 300);
// Canvas 3
var canvas3 = document.getElementById("canvas3");
var context3 = canvas3.getContext("2d");
photo3 = document.getElementById("red2");
function drawImage() {
for (var x = 0; x < 6; x++) {
for (var y =0; y < 6; y++ ) {
context3.drawImage(photo3, x * 100, y * 75, 100, 75);
}
}
}
window.addEventListener("load", drawImage, false);
Since you're loading the script in the <head>, everything is running before the DOM is loaded, so all your getElementBuId() calls are failing. You either need to put the <script> tag at the end of the <body>, or put all the code into a window.onload function, e.g.
window.onload = function() {
var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
photo = document.getElementById("red");
function drawImage() {
context.drawImage(photo, 0, 0);
}
window.addEventListener("load", drawImage, false);
...
};
This has the added benefit of not polluting the global namespace.
I'll second what Barmar said. In general, I load my JavaScript at the end of the html for better performance, and so I'm sure I won't have this issue.

Canvas images are fuzzy and not complete

I tried every example that is on internet and NONE of them is working.
I tried to get a full image into a canvas, but it's zoomed in with really bad quality.
I tried rotate (standing pictures need to be laying) and I need the dataurl back.
Getting the dataurl was not the problem.
The problem is that it doesn't work.
<script>
function readFile(file, callback){
var reader = new FileReader();
reader.onload = callback
reader.readAsDataURL(file);
result = reader.readAsDataURL(file);
console.log(result);
}
function snapitgetFile(){
snapitloadshit();
}
function snapitloadshit(){
$('#snapitUpload').on('change', function(e){
var filesize = this.files[0].size;
var filename = this.files[0].name;
var extension = filename.substring(filename.lastIndexOf('.')+1);
var filePath = $(this).val();
readFile(this.files[0], function(e) {
//console.log(e.target.result);
var canvas = document.getElementById("pic");
var ctx = canvas.getContext("2d");
var image = new Image();
image.onload = function() {
var imgwidth = this.width;
var imgheigt = this.height;
$('#pic').css('height', imgheigt);
$('#pic').css('width', imgwidth);
ctx.drawImage(image, 0,0);
};
image.src = e.target.result;
});
});
}
</script>
demo: http://www.aeglobalresearch.com/demo/rotate.html
Try to select a picture and you see what I mean.
I googled and checked here, but all examples makes the picture look ugly or moves them to weird position.
I just want to get load the picture, rotate 90 degrees so a picture that is standing is laying.
Get the dataurl and than the rest of my script will do the rest.
Keeping all the exif, it just need to rotate 90 degrees right that's all.
What I'm doing wrong
Do the rotation like this:
make the canvas the same size as the image (as #Akaryatrh says),
translate to the center of the image,
rotate by 90 degrees (==90*Math.PI/180)
draw the image offset by -img.width/2 and -img.height/2
Demo: http://jsfiddle.net/m1erickson/NZZ3s/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image();img.onload=start;img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/2014.png";
function start(){
canvas.width=img.width;
canvas.height=img.height;
ctx.translate(img.width/2,img.height/2);
ctx.rotate(90 * Math.PI/180);
ctx.drawImage(img,-img.width/2,-img.height/2);
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
Replace these lines :
$('#pic').css('height', imgheigt);
$('#pic').css('width', imgwidth)
With this :
canvas.height = imgheigt;
canvas.width = imgwidth;
Actually you were setting width and height css styles to your canvas, while you were supposed to modify element attributes.
[EDIT] Here's a full solution on jsfiddle with 90° rotation : http://jsfiddle.net/Akaryatrh/r6u9c/

Categories