【问题标题】:Javascript image manipulation? Pixel by pixelJavascript图像处理?逐个像素
【发布时间】:2011-08-17 14:03:15
【问题描述】:

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

【问题讨论】:

  • 几个月前我在 Silverlight 中做到了,我不相信任何事情都是不可能的,只要我能让用户选择我想阅读的图像。甚至逐字节读取数据也是一种解决方案(我在 Silverlight 中这样做了)。所以我只需要用什么来减少开发时间:D
  • @denisk,可能重复,但我也需要任何可以帮助我实现目标的想法

标签: javascript jquery image-processing


【解决方案1】:

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

【讨论】:

  • 所以我认为画布是要走的路,只要我什至不支持 ie9 :D
  • 你很幸运。有时我希望我可以开发一个不需要支持 any 的基于 Web 的应用程序,即 :)
【解决方案2】:

我发现这个库看起来很有趣: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

【讨论】:

  • 我昨天看了它的代码,它基本上是在画布上进行操作,所以如果没有其他办法,我会去的
  • 所以我认为画布是要走的路,只要我什至不支持 ie9 :D 谢谢你,但我不能选择你的答案,因为 MeLight 回答得更早
【解决方案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>

处理画布的代码

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

【讨论】:

  • 应该绝对是公认的答案!感谢您提供这样的文档
猜你喜欢
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多