快速图像缩小?

时间:2017-03-06 05:23:36

标签: javascript performance canvas graphics

我正在写一个“电视滤镜”(你知道放大时的那种RGB条),一个视频文件,我一直在看一些缩小图像的方法,保留了很多细节尽可能。

为了测试我正在将采样的图像绘制回屏幕以查看质量 - 在实际的滤镜中,我只是采样像素并获得所得计算颜色的RGB值。

我已经试过三次了,Hermite过滤器看起来不错,但与速度“硬件”最近邻版相比,它不适合处理视频。

JavaScript中是否有任何“技巧”可用于加速图像缩小,如2,但质量如1或3?

1:蛮力:http://codepen.io/SarahC/pen/VpvWvb?editors=1010

2:内部最近邻居:http://codepen.io/SarahC/pen/ryeQgN?editors=1010

3:Hermite过滤器:http://codepen.io/SarahC/pen/ryMNWZ?editors=1010

这是“硬件”?版本:

function processResize(percent) {
  var size = percent * 0.01;
  var sw = canvas.width * size;
  var sh = canvas.height * size;
  ctx.drawImage(canvas2, 0, 0, sw, sh);
  ctx.drawImage(canvas, 0, 0, sw, sh, 0, 0, w, h);
}

1 个答案:

答案 0 :(得分:1)

我不完全确定你要尝试实现的描述,但是当你尝试创建马赛克效果时,似乎从codepens中。

您可以使用画布上下文的内置插值设置通过关闭图像平滑来使用最近邻居,然后将图像绘制为一个小尺寸,表示您想要多少“块”。然后再将该版本拉回到完整尺寸:

// blocks = initial number of pixels (video aspect is usually 16:9 so you may want
// to calculate a separate values for height.
var blocks = 24;

// draw initial size representing "blocks"
ctx.drawImage(video, 0, 0, blocks, blocks);

// turn off image smoothing (see below for prefixing)
// This uses nearest neighbor
ctx.imageSmoothingEnabled = false;

// enlarge the mosaic back to full size
ctx.drawImage(c, 0, 0, blocks, blocks, 0, 0, c.width, c.height);

视频示例

(视频可能需要几秒钟才能加载...)

var ctx = null;
var blocks = 24;
var video = document.createElement("video");
video.preload = "auto"; video.muted = video.autoplay = video.loop = true;
video.oncanplay = function() {  // initialize for demo
  if (!ctx) {
    c.width = this.videoWidth;
    c.height = this.videoHeight;
    ctx = c.getContext("2d");

    document.querySelector("input").oninput = function() {blocks = +this.value};
    requestAnimationFrame(loop);
  }
}
video.src = "//media.w3.org/2010/05/sintel/trailer.mp4";

function smoothing(state) {
  ctx.oImageSmoothingEnabled = ctx.msImageSmoothingEnabled =
  ctx.mozImageSmoothingEnabled = ctx.webkitImageSmoothingEnabled =
  ctx.imageSmoothingEnabled = state;
}

function loop() {
  smoothing(true);  // improve quality of first step
  ctx.drawImage(video, 0, 0, blocks, blocks);

  smoothing(false); // mosaic step
  ctx.drawImage(c, 0, 0, blocks, blocks, 0, 0, c.width, c.height);
  
  // loop and throttle to 30 fps
  requestAnimationFrame(function() {requestAnimationFrame(loop)});
}
<label>Blocks: <input type=range min=8 max=128 value=24></label><br>
<canvas id=c></canvas>

相关问题