使用Javascript或WebAssembly进行图像插值

问题描述 投票:0回答:1

我有一幅画,我在画布上逐像素绘制。图片尺寸:512 *256。当我将此图片制作为1536 * 768时,图片看起来非常糟糕。我想我可以使用插值来解决此问题。但是我找不到一个好的JavaScript库。在我发现的库中它不起作用。

我的代码如下。我根据这些值找到了等效的颜色,并将其反映在屏幕上。

function ImageData(ctx, points) {

    var data = ctx.createImageData(512, 256);

    for (var i = 0; i < data.data.length; i += 4)
    {
        var colorIndex = GetColorCode(points[i/4], minColorIndex, maxColorIndex);
        var color = colormap[colorIndex];

        data.data[i+0] = color[0];
        data.data[i+1] = color[1];
        data.data[i+2] = color[2];
        data.data[i+3] = 255;
    }

    return data;
}

function Draw (points)
{
    var canvas = document.getElementById("myCanvas");
    canvas.width = width;
    canvas.height = height;
    var ctx = canvas.getContext("2d");
    var data = ImageData(ctx, points);

    ctx.putImageData(data, 0, 0);
}

有人可以帮助我吗?

javascript image-processing canvas interpolation webassembly
1个回答
1
投票

重新采样ImageData的简单方法是将其放到其实际大小,然后通过简单地使用drawImage对其进行绘制,重新缩放目标画布。

const canvas = document.getElementById( 'canvas' );
const ctx = canvas.getContext( '2d' );
// prepare our 50*50 ImageData
const data = new Uint32Array( 50 * 50 );
crypto.getRandomValues( data ); // make some noise
const imgData = new ImageData( new Uint8ClampedArray( data.buffer ), 50, 50 );
// put it on canvas @scale(1)
ctx.putImageData( imgData, 0, 0 );
// at this step, our canvas only contains this 50*50 ImageData

// resize using the default interpolation

// we first change the composite mode to be able to clear while drawing
ctx.globalCompositeOperation = "copy";
ctx.scale( 10, 10 ); // so 500x500
// newest browsers can control interpolation quality
ctx.imageSmoothingQuality = "high";
ctx.drawImage( canvas, 0, 0 );

// clean
ctx.globalCompositeOperation = "source-over";
ctx.setTransform( 1, 0, 0, 1, 0, 0);
<canvas id="canvas" width="500" height="500"></canvas>

并且要避免插值(最近的邻居),然后执行相同的操作,但是将imageSmoothingEnabled设置为false:

const canvas = document.getElementById( 'canvas' );
const ctx = canvas.getContext( '2d' );

const data = new Uint32Array( 50 * 50 );
crypto.getRandomValues( data ); // make some noise
const imgData = new ImageData( new Uint8ClampedArray( data.buffer ), 50, 50 );

ctx.putImageData( imgData, 0, 0 );

ctx.globalCompositeOperation = "copy";
ctx.scale( 10, 10 ); // so 500x500

ctx.imageSmoothingEnabled = false;
ctx.drawImage( canvas, 0, 0 );

// clean
ctx.imageSmoothingEnabled = true;
ctx.globalCompositeOperation = "source-over";
ctx.setTransform( 1, 0, 0, 1, 0, 0);
<canvas id="canvas" width="500" height="500"></canvas>
© www.soinside.com 2019 - 2024. All rights reserved.