我正在尝试使用javascript对图像执行简单操作。为了获得图像的像素,我在画布上绘制图像,然后从画布中获取ImageData。但对于大型图像,在画布上绘制它们需要花费大量时间。
有没有其他方法可以在不使用canvas元素的情况下获取图像像素?
答案 0 :(得分:2)
我不认为您可以通过硬件加速在JavaScript中进行图像处理,因此无论是画布还是其他技术,您都无法在JavaScript环境中获得太多的边际优势。
如果您希望代码是硬件加速的,则必须将代码编译为在GPU中运行并可访问图形内存的代码。 Flash和Silverlight的方法是引入像AGAL和HLSL这样的着色语言。也许JavaScript将来会有这样的东西。
所以我的建议是用以下方式进行图像处理:
答案 1 :(得分:1)
我没有太多使用Javascript的经验,但Max Novakovic(@betamax)写了一个很好的小型jQuery插件,名为 $ .getImageData ,这可能会有所帮助。
您可以在disturb blog和plugin page上了解有关 $ .getImageData 的更多信息
您应该可以通过context.getImageData(x, y, width, height).data
等内容访问像素。
此外,您提到了硬件加速,这应该在Firefox4和Chrome中可用。 Shadertoy在浏览器中使用GLSL着色器:
答案 2 :(得分:0)
我不确定,但是可以将图像数据写成字符串,然后操纵字符串,然后在显示结果图像之前将其转换回图像?
这不需要绘制到画布,只需将图像数据作为字符串而不是图像加载。然而,它将涉及一些复杂的并且可能难以获得正确的字符串操作,以确保正确地转换图像数据并且还操纵像素。
这也意味着字符串对于较大的图像可能会非常长,因此这可能比画布需要更多的内存,并且可能需要拆分成多个字符串。作为交换,它可能比绘制到画布更快,特别是对于多个字符串,如果您只需要操作部分图像。
我对图像处理没有经验,但理论上没有理由不能将文件的数据写入字符串。它再次构成一个非常长的字符串并因此而产生可能的RAM影响,因为该字符串可能占用比映像文件本身更多的RAM。但它的加载速度会更快,因为它不需要像绘制到画布那样处理数据。
答案 3 :(得分:0)
以下示例使用MarvinJ。它采用具有2800x2053分辨率的彩色图像,遍历每个像素计算灰度值并将其设置回来。在画布上方有一个div来打印处理时间。在我的机器上, 115ms 包括图像加载。
var time = new Date().getTime();
var canvas = document.getElementById("canvas");
image = new MarvinImage();
image.load("https://i.imgur.com/iuGXHFj.jpg", imageLoaded);
function imageLoaded(){
for(var y=0; y<image.getHeight(); y++){
for(var x=0; x<image.getWidth(); x++){
var r = image.getIntComponent0(x,y);
var g = image.getIntComponent1(x,y);
var b = image.getIntComponent2(x,y);
var gray = Math.floor(r * 0.21 + g * 0.72 + b * 0.07);
image.setIntColor(x,y,255,gray,gray,gray);
}
}
image.draw(canvas);
$("#time").html("Processing time: "+(new Date().getTime()-time)+"ms");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.marvinj.org/releases/marvinj-0.7.js"></script>
<div id="time"></div>
<canvas id="canvas" width="2800" height="2053"></canvas>