像素化图像数据算法非常慢 [英] Pixelate Image Data Algorithm very slow
问题描述
我在工具中使用了像素化算法,但是当我今天将其应用于绘图应用程序时,它的性能非常糟糕。我想知道您是否可以帮助我。
I had this pixelate algorithm in my tools, but when I came to apply it today to my drawing app, it's performance is seriously bad. I was wondering if you could help me with this.
这是我的算法:
//apply pixalate algorithm
for(var x = 1; x < w; x += aOptions.blockSize)
{
for(var y = 1; y < h; y += aOptions.blockSize)
{
var pixel = sctx.getImageData(x, y, 1, 1);
dctx.fillStyle = "rgb("+pixel.data[0]+","+pixel.data[1]+","+pixel.data[2]+")";
dctx.fillRect(x, y, x + aOptions.blockSize - 1, y + aOptions.blockSize - 1);
}
}
我想知道您是否可以帮助我加快速度,我不确定是什么原因导致此PERF命中。
I was wondering if you could help me speed it up, I'm not sure whats causing this perf hit.
(是的,我知道imageSmoothingEnabledEnabled技术,但是它不能完全控制块大小)
(yes i know the imageSmoothingEnabled techqnique however its not giving me perfect control over the block size)
推荐答案
您为每个像素获取一个 ImageData
对象,然后构造一个具有由canvas对象再次解析,然后使用canvas填充例程,该例程必须遍历所有画布设置(转换矩阵,合成等)。
You fetch an ImageData
object for each pixel, then construct a colour string which has to be parsed again by the canvas object and then use a canvas fill routine, which has to go through all the canvas settings (transformation matrix, composition etc.)
似乎绘制的矩形比实际需要的大: fillRect
的第三个和第四个参数是宽度和高度,而不是 x
和 y
与右下角协调。为什么从像素1开始而不是从零开始?
You also seem to paint rectangles that are bigger than they need to be: The third and fourth parameters to fillRect
are the width and height, not the x
and y
coordinated of the lower right point. An why do you start at pixel 1, not at zero?
处理原始数据进行像素操作通常要快得多。提取整个图像作为图像数据,对其进行处理,最后将其放在目标画布上:
It is usually much faster to operate on raw data for pixel manipulations. Fetch the whole image as image data, manipulate it and finally put it on the destination canvas:
var idata = sctx.getImageData(0, 0, w, h);
var data = idata.data;
var wmax = ((w / blockSize) | 0) * blockSize;
var wrest = w - wmax;
var hmax = ((h / blockSize) | 0) * blockSize;
var hrest = h - hmax;
var hh = blockSize;
for (var y = 0; y < h; y += blockSize) {
var ww = blockSize;
if (y == hmax) hh = hrest;
for (var x = 0; x < w; x += blockSize) {
var n = 4 * (w * y + x);
var r = data[n];
var g = data[n + 1];
var b = data[n + 2];
var a = data[n + 3];
if (x == wmax) ww = wrest;
for (var j = 0; j < hh; j++) {
var m = n + 4 * (w * j);
for (var i = 0; i < ww; i++) {
data[m++] = r;
data[m++] = g;
data[m++] = b;
data[m++] = a;
}
}
}
}
dctx.putImageData(idata, 0, 0);
在我的浏览器中,即使有两个附加的内部循环,速度也更快。
In my browser, that's faster even with the two additonal inner loops.
这篇关于像素化图像数据算法非常慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!