I'd like to know if there is a way to dynamically modify/access the data contained in html images just as if they were an html5 canvas element. With canvas, you can in javascript access the raw pixel data with getImageData() and putImageData(), but I have thus far been not able to figure out how to do this with images.
7 Answers
// 1) Create a canvas, either on the page or simply in code
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// 2) Copy your image data into the canvas
var myImgElement = document.getElementById('foo');
ctx.drawImage( myImgElement, 0, 0 );
// 3) Read your image data
var w = myImgElement.width, h=myImgElement.height;
var imgdata = ctx.getImageData(0,0,w,h);
var rgba = imgdata.data;
// 4) Read or manipulate the rgba as you wish
for (var px=0,ct=w*h*4;px<ct;px+=4){
var r = rgba[px ];
var g = rgba[px+1];
var b = rgba[px+2];
var a = rgba[px+3];
}
// 5) Update the context with newly-modified data
ctx.putImageData(imgdata,0,0);
// 6) Draw the image data elsewhere, if you wish
someOtherContext.drawImage( ctx.canvas, 0, 0 );
Note that step 2 can also be brought in from an image loaded directly into script, not on the page:
// 2b) Load an image from which to get data
var img = new Image;
img.onload = function(){
ctx.drawImage( img, 0, 0 );
// ...and then steps 3 and on
};
img.src = "/images/foo.png"; // set this *after* onload
-
your code does not work, someOtherContext.drawImage(ctx,0,0); keeps throwing "Type error" because first attribute must be image, not context (chrome 7, firefox 3.6) – Nov 30 '10 at 22:05
-
1If one wants to iterate over all pixels in the image, step 4 should be ...ct=w*h*4... since there are four values per pixel. – pettys Mar 07 '12 at 14:17
-
@dvh I think it was intended to be "canvas" instead of ctx. drawImage can take either an image or a canvas. – pettys Mar 07 '12 at 14:27
-
3Note that browsers now have a cross-origin security restriction on getting data from a `canvas` after it has had image data from outside the domain written to it. Chrome's message, for instance, says `"Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data."` – brichins Jun 08 '16 at 14:59
You could draw the image to a canvas element with drawImage(), and then get the pixel data from the canvas.

- 16,175
- 3
- 52
- 51
-
2This does not allow me to put manipulate the image data itself tho, which is what I want to do. – Ahi Tuna Sep 22 '09 at 21:44
-
5Once the image has been copied to the `canvas` element, you can manipulate it any way you would normally manipulate `canvas` pixel data. – Alex Barrett Oct 13 '09 at 00:00
After having some issues with this code, I want to add one or two things to Phrogz's answer :
// 1) Create a canvas, either on the page or simply in code
var myImgElement = document.getElementById('foo');
var w = myImgElement.width, h=myImgElement.height; // New : you need to set the canvas size if you don't want bug with images that makes more than 300*150
var canvas = document.createElement('canvas');
canvas.height = h;
canvas.width = w;
var ctx = canvas.getContext('2d');
// 2) Copy your image data into the canvas
ctx.drawImage( myImgElement, 0, 0, w, h ); // Just in case...
// 3) Read your image data
var imgdata = ctx.getImageData(0,0,w,h);
var rgba = imgdata.data;
// And then continue as in the other code !
that worked for me (IE10x64,Chromex64 on win7, chromium arm linux, ...seems to bug with firefox 20 arm linux but not sure ... to re-test)
--html--
<canvas id="myCanvas" width="600" height="300"></canvas>
<canvas id="myCanvasOffscreen" width="1" height="1"></canvas>
-- js --
// width & height can be used to scale image !!!
function getImageAsImageData(url, width, height, callack) {
var canvas = document.getElementById('myCanvasOffscreen');
canvas.width = width;
canvas.height = height;
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0, width, height);
imgData = context.getImageData(0,0,width, height);
canvas.width = 1;
canvas.height = 1;
callack( imgData );
};
imageObj.src = url;
}
-- then --
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var imgData;
getImageAsImageData('central_closed.png', IMG_WIDTH, IMG_HEIGHT,
function(imgData) {
// do what you want with imgData.data (rgba array)
// ex. colorize( imgData, 25, 70, 0);
ctx.putImageData(imgData,0,0);
}
);

- 86
- 2
you first want to draw a pic on the canvas and then get the imageData from the canvas ,it is a wrong way,because the js think it is a "Cross-domain access",but the getIamgeData method don't allow the "Cross-domain access" to an image.you can hava a try by put the in the root place and access it by "localhost" .

- 11
- 1
Im not sure if it is possible, but you can try requesting pixel information from PHP, if GD library it will be an easy task, but surely will be slower. Since you didnt specified application so I will suggest checking SVG for this task if they can be vector images than you will be able to query or modify the image.

- 14,120
- 4
- 40
- 62
-
2I wanted to do this entirely in the browser, not use any server side scripting at all. – Ahi Tuna Sep 22 '09 at 21:44
-
Can you give some details, its pretty impossible to do it but there might be alternative solutions. – Cem Kalyoncu Sep 23 '09 at 07:23
-
2if i were to actually implement this in some software, i would probably update the DOM node of the image. However, my question was aimed more at the level of "is this even possible?" to learn more about html itself. – Ahi Tuna Sep 23 '09 at 18:34
Directly work on IMG element is also valid:
var image = document.createElement('img'),w,h ;
image.src = "img/test.jpg" ;
$(image).one('load',function(){
w = image.naturalWidth ;
h = image.naturalHeight ;
var cnv = document.createElement('canvas') ;
$(cnv).attr("width",w) ;
$(cnv).attr("height",h) ;
var ctx = cnv.getContext('2d') ;
ctx.drawImage(image,0,0) ;
var imgdata = ctx.getImageData(0,0,w,h) ;
var rgba = imgdata.data ;
for (var px=0,ct=w*h*4;px<ct;px+=4){
var r = rgba[px+0] ;
var g = rgba[px+1] ;
var b = rgba[px+2] ;
var a = rgba[px+3] ;
// Do something
rgba[px+0] = r ;
rgba[px+1] = g ;
rgba[px+2] = b ;
rgba[px+3] = a ;
}
ctx.putImageData(imgdata,0,0) ;
$("body").append(cnv) ;
}) ;

- 1,826
- 4
- 24
- 39