Javascript image manipulation? Pixel by pixel
Is there a way or a library to obtain an images color data pixel by pi开发者_JAVA技巧xel in javascript? I need to read lots of OMR form, and i want to do it on clients not on my server :D. So either i can build it the system with javascript if i can reach raw data or i have to build a desktop application which i don't like at all. Thanks
Sure, no need to use libraries. It's really simple through canvases.
img -> canvas -> magic -> canvas -> img
What you need is to:
- create
<canvas>
- get canvas
context
- copy
img
tocanvas
- get canvas
image data
(an array of values[r,g,b,a,r,g,b,a,r,g,..]
) - do `The magic`®
- put
image data
back - put changed
canvas
back to<img>
the code to deal with canvas
var cvs = document.createElement('canvas'),
img = document.getElementsByTagName("img")[0]; // your image goes here
// img = $('#yourImage')[0]; // can use jquery for selection
cvs.width = img.width; cvs.height = img.height;
var ctx = cvs.getContext("2d");
ctx.drawImage(img,0,0,cvs.width,cvs.height);
var idt = ctx.getImageData(0,0,cvs.width,cvs.height);
// usage
getPixel(idt, 852); // returns array [red, green, blue, alpha]
getPixelXY(idt, 1,1); // same pixel using x,y
setPixelXY(idt, 1,1, 0,0,0,255); // a black pixel
6,7, modify the image ...
ctx.putImageData(idt, 0,0); // 0,0 is xy coordinates
img.src = cvs.toDataURL();
wondered where the canvas is?
document.body.appendChild(cvs);
some magic functions
Since the image data
are an array of consecutive r,g,b,a,r,g,..
values and one pixel consists of 4 values, you need to recalculate indexes. The formula is simple: data[(y*width + x)*4 + ch]
, where ch
is between 0
and 3
for r,g,b,a
channels.
Note that there is more concise and also faster solution below.
function getPixel(imgData, index) {
var i = index*4, d = imgData.data;
return [d[i],d[i+1],d[i+2],d[i+3]] // [R,G,B,A]
}
function getPixelXY(imgData, x, y) {
return getPixel(imgData, y*imgData.width+x);
}
function setPixel(imgData, index, r, g, b, a) {
var i = index*4, d = imgData.data;
d[i] = r;
d[i+1] = g;
d[i+2] = b;
d[i+3] = a;
}
function setPixelXY(imgData, x, y, r, g, b, a) {
return setPixel(imgData, y*imgData.width+x, r, g, b, a);
}
update 2019 Uint8ClampedArray
You can manipulate pixel data directly with this subarray "view".
subarray
is different from slice
or from previous example in that it does not create a shallow copy of the array but an array that shares the same store.
Read more at MDN:Uint8ClampedArray.
function getPixel(imgData, index) {
return imgData.data.subarray(index*4, index*4+4) // Uint8ClampedArray(4) [R,G,B,A]
}
let px = getPixelXY(idt, 0, 0)
px[0] = 255
// ctx.putImageData(idt,0,0); // makes the pixel reddish
or
function getPixel(imgData, index) {
return imgData.data.slice(index*4, index*4+4) // [R,G,B,A]
}
function setPixel(imgData, index, pixelData /*[R,G,B,A]*/) {
imgData.data.set(pixelData, index*4)
}
HTML5 Canvas element is the way to go if you don't have browser limitations.
I found this library which seems interesting : http://www.pixastic.com/
It can make a color histogram of your picture so I guess If you inspect the code a bit .. But It doesn't seems to work with IE ..
I guess this part is interesting for you :
var ctx = params.canvas.getContext("2d");
var rect = params.options.rect;
var dataDesc = ctx.getImageData(rect.left, rect.top, rect.width, rect.height);
var data = dataDesc.data;
if (!getCopy) params.canvasData = dataDesc;
return data;
from pixtastic.core.js prepareData
function
You can also find interesting info here : What is leaking memory with this use of getImageData, javascript, HTML5 canvas
精彩评论