Javascript 图像处理?逐像素

gka*_*kck 5 javascript jquery image-processing

有没有办法或库在javascript中逐个像素地获取图像颜色数据?我需要阅读大量 OMR 表格,我想在客户端而不是我的服务器上执行此操作:D。因此,如果我可以访问原始数据,我可以使用 javascript 构建系统,或者我必须构建一个我根本不喜欢的桌面应用程序。谢谢

Qwe*_*rty 13

当然,不需要使用库。通过canvases真的很简单。

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

你需要的是:

  1. 创建 <canvas>
  2. 获取画布 context
  3. 复制imgcanvas
  4. 获取画布image data(一组值[r,g,b,a,r,g,b,a,r,g,..]
  5. 做`魔术`®
     
  6. image data回去
  7. 把改canvas<img>

处理画布的代码

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
Run Code Online (Sandbox Code Playgroud)

6,7、修改图片...

ctx.putImageData(idt, 0,0);  // 0,0 is xy coordinates
img.src = cvs.toDataURL();
Run Code Online (Sandbox Code Playgroud)

想知道画布在哪里?

document.body.appendChild(cvs);
Run Code Online (Sandbox Code Playgroud)

一些神奇的功能

由于image data是一组连续r,g,b,a,r,g,..值,并且一个像素由 4 个值组成,因此您需要重新计算索引。式很简单:data[(y*width + x)*4 + ch],其中,ch是间03r,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);
}
Run Code Online (Sandbox Code Playgroud)

更新 2019 Uint8ClampedArray

您可以直接使用此子数组 "view"操作像素数据。 与前一个示例的subarray不同之处slice在于它不创建数组的浅拷贝,而是创建共享相同存储的数组。

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
Run Code Online (Sandbox Code Playgroud)

或者

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)
}
Run Code Online (Sandbox Code Playgroud)


MeL*_*ght 3

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

  • 幸运的你。我有时希望我可以开发一个基于网络的应用程序,不需要支持_any_ ie :) (3认同)