双线性scalling算法奇怪的效果

时间:2015-08-02 22:03:43

标签: javascript algorithm image-processing typescript

我写了一个算法来通过billinear scalling方法来缩放图像,但它并没有像预期的那样工作。我真的找不到我的代码中的任何错误,但它产生了错误的输出:

enter image description here

    Process(context: ImageData): ImageData {
        var imageData = context;

        var w = imageData.width;
        var h = imageData.height;

        var small = new Uint32Array((<any>imageData.data).buffer);
        var big = new Uint32Array(small.length * (this.factor * this.factor));

        var w2 = this.factor * imageData.width;
        var h2 = this.factor * imageData.height;

        var x_ratio = ((w) / w2);
        var y_ratio = ((h) / h2);

        for (var i = 0, f = h2; i < f; ++i) {

            var py_a = (i * y_ratio);
            var py = py_a | 0;
            var py_t = py_a - py;

            for (var j = 0, k = w2; j < k; ++j) {
                var px_a = (j * x_ratio);
                var px =  px_a | 0;
                var index = ((py * w) + px) | 0;

                var px_t = px_a - px;

                var fy1 = small[index] + (small[index + 1] - small[index]) * px_t;
                var fy2 = small[index + w] + (small[index + w + 1] - small[index + w]) * px_t;

                var tmp = fy1 + (fy2 - fy1) * py_t;

                big[i * w2 + j] = tmp;
            }
        }

        var ar = new Uint8ClampedArray(big.buffer);
        var newImage = new ImageData(ar, w2, h2);

        return newImage;
    }

我通常想知道如果我可以一起对待每个频道,还是应该分开(至少是alpha)呢?

2 个答案:

答案 0 :(得分:2)

必须拆分频道。他们都是。然后彼此独立插值。

否则它们将以奇怪的方式干涉,例如,如果您在纯白色和纯黑色之间进行插值而不进行分割,假设插值非常精细(大约2 24 像素宽),朝向黑色结束你变红(最低位的通道),渐渐变红,直到溢出成一个非常深的绿色,然后重新开始,但稍微多一点绿色混合,重复这个模式几次,直到最后重新开始再次,但蓝色混合在一起。更粗糙的插值基本上以规则的间隔对奇怪的彩虹进行采样。

分别对通道进行插值会使所有通道以相同的速率增加(并且不会定期回到零)朝向白色端,从而产生灰色渐变,这是预期的。

答案 1 :(得分:1)

如果数据是RGBA值(如harold所示),则下一个像素的相应分量不在下一个字节中,它距离四个字节,并且行的宽度不是{{ 1}}个字节,但w个字节。

那会产生代码:

w * 4