Javascript图像处理?逐像素

时间:2011-05-03 09:44:08

标签: javascript jquery image-processing

有没有办法或图书馆在javascript中逐像素地获取图像颜色数据? 我需要阅读很多OMR表单,我想在不在我服务器上的客户端上进行:D。所以要么我可以使用javascript构建它,如果我可以达到原始数据,或者我必须构建一个我根本不喜欢的桌面应用程序。 感谢

3 个答案:

答案 0 :(得分:3)

如果您没有浏览器限制,HTML5 Canvas元素就是您的选择。

答案 1 :(得分:3)

我发现这个图书馆看起来很有趣:http://www.pixastic.com/

它可以制作你的图片的color histogram,所以我想如果你稍微检查一下代码.. 但它似乎不适用于IE ..

我想这部分对你很有意思:

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;

来自pixtastic.core.js prepareData函数

您还可以在此处找到有趣的信息:What is leaking memory with this use of getImageData, javascript, HTML5 canvas

答案 2 :(得分:3)

当然,不需要使用库。通过画布非常简单。

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

您需要的是:

  1. 创建<canvas>
  2. 获取画布context
  3. img复制到canvas
  4. 获取画布image data(值数组[r,g,b,a,r,g,b,a,r,g,..]
  5. 做`魔术`®
  6. 放回image data
  7. 将更改后的canvas更改回<img>
  8. 处理画布的代码

    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,修改图片......

    ctx.putImageData(idt, 0,0);  // 0,0 is xy coordinates
    img.src = cvs.toDataURL();
    

    想知道画布在哪里?

    document.body.appendChild(cvs);
    

    一些神奇的功能

    由于image data是连续r,g,b,a,r,g,..值的数组,而一个像素由4个值组成,因此需要重新计算索引。公式很简单:data[(y*width + x)*4 + ch],其中ch介于03之间,用于r,g,b,a个渠道。

    请注意,下面有更简洁,更快的解决方案。

    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);
    }
    

    更新2019 Uint8ClampedArray

    您可以使用此subarray “视图”直接操作像素数据。 subarrayslice或前一个示例的不同之处在于它不会创建数组的浅表副本,而是创建共享同一存储的数组。

    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
    

    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)
    }