最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - Javascript image manipulation? Pixel by pixel - Stack Overflow

programmeradmin3浏览0评论

Is there a way or a library to obtain an images color data pixel by pixel 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

Is there a way or a library to obtain an images color data pixel by pixel 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

Share Improve this question asked May 3, 2011 at 9:44 gkaykckgkaykck 2,36711 gold badges35 silver badges52 bronze badges 3
  • possible duplicate of stackoverflow.com/questions/1041399/… – Denys Kniazhev-Support Ukraine Commented May 3, 2011 at 9:51
  • i did it in silverlight a few months ago, and i don't believe that anything is impossible as long as i can get the user select images i want to read. Even reading the data byte by byte can be a solution(i did it this way in silverlight). So i just need what to use to reduce development time :D – gkaykck Commented May 3, 2011 at 9:51
  • @denisk, possible duplicate, but i also need any ideas that might help me achieve the goal – gkaykck Commented May 3, 2011 at 9:53
Add a comment  | 

3 Answers 3

Reset to default 15

Sure, no need to use libraries. It's really simple through canvases.

img -> canvas -> magic -> canvas -> img

What you need is to:

  1. create <canvas>
  2. get canvas context
  3. copy img to canvas
  4. get canvas image data (an array of values [r,g,b,a,r,g,b,a,r,g,..])
  5. do `The magic`®
     
  6. put image data back
  7. 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

发布评论

评论列表(0)

  1. 暂无评论