像素化图像数据算法非常慢 [英] Pixelate Image Data Algorithm very slow

查看:199
本文介绍了像素化图像数据算法非常慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在工具中使用了像素化算法,但是当我今天将其应用于绘图应用程序时,它的性能非常糟糕。我想知道您是否可以帮助我。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆