如何在没有抗锯齿的情况下拉伸图像

Tim*_*ler 38 javascript css image-manipulation image

所以我最近碰到了这个:http://www.nicalis.com/index.php

我很好奇:有没有办法用较小的图像做这种事情?我的意思是,它是像素艺术,而不是使用每个像素大小翻两番的图像,我们不能用代码拉伸它们吗?所以我开始尝试实现它.

我尝试过CSS,Javascript甚至HTML,但都没有.它们都非常糟糕(如下所示:http://jsfiddle.net/nUVJt/2/),这让我想到了一个问题:你可以在没有任何抗锯齿的情况下在浏览器中拉伸图像吗?

我对任何建议持开放态度,无论是使用画布,jQuery,CSS3还是其他什么.

谢谢您的帮助!

编辑:现在有更好的方法来做到这一点!一种稍微不那么强硬的方式!这是魔术:

.pixelated {
    image-rendering: -moz-crisp-edges;
    image-rendering: -o-crisp-edges;
    image-rendering: -webkit-optimize-contrast;
    -ms-interpolation-mode: nearest-neighbor;
    image-rendering: pixelated;
}
Run Code Online (Sandbox Code Playgroud)

这将阻止所有现代浏览器中的抗锯齿.它甚至可以在IE7-8中工作,但不会在9中工作,我不知道有什么办法在9中做到这一点,不幸的是(除了下面概述的画布黑客).与JS相比,用这种方式做得多快得多.以下是有关这些内容的更多信息:https://developer.mozilla.org/en-US/docs/CSS/Image-rendering

EDIT2:因为这还不是官方规范,所以它不太可靠.Chrome和FF似乎都停止支持它,因为我写了上面的内容(根据下面提到的这篇文章),这真的很烦人.在我们真正开始在CSS中使用它之前,我们可能还需要等待几年,这真的很不幸.

最终编辑:现在有一种官方方式可以做到这一点!有一个叫做的新房产image-rendering.这是CSS3规范.支持现在非常不稳定,但Chrome只是增加了支持,所以在不久之后我们就能说出来image-rendering: pixelated;并且它可以在所有地方工作(yaayy常青浏览器!)

Aln*_*tak 18

Canvas文档明确没有指定缩放方法 - 在我自己的测试中,它确实在Firefox中对图像进行了非常反混淆.

下面的代码从源图像(必须来自相同的Origin或数据URI)逐个像素地复制,并按指定的因子进行缩放.

需要额外的离屏画布(src_canvas)来接收原始源图像,然后将其图像数据逐个像素地复制到屏幕画布上.

var img = new Image();
img.src = ...;
img.onload = function() {

    var scale = 8;

    var src_canvas = document.createElement('canvas');
    src_canvas.width = this.width;
    src_canvas.height = this.height;

    var src_ctx = src_canvas.getContext('2d');
    src_ctx.drawImage(this, 0, 0);
    var src_data = src_ctx.getImageData(0, 0, this.width, this.height).data;

    var dst_canvas = document.getElementById('canvas');
    dst_canvas.width = this.width * scale;
    dst_canvas.height = this.height * scale;
    var dst_ctx = dst_canvas.getContext('2d');

    var offset = 0;
    for (var y = 0; y < this.height; ++y) {
        for (var x = 0; x < this.width; ++x) {
            var r = src_data[offset++];
            var g = src_data[offset++];
            var b = src_data[offset++];
            var a = src_data[offset++] / 100.0;
            dst_ctx.fillStyle = 'rgba(' + [r, g, b, a].join(',') + ')';
            dst_ctx.fillRect(x * scale, y * scale, scale, scale);
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/alnitak/LwJJR/的工作演示

编辑更优化的演示可在http://jsfiddle.net/alnitak/j8YTe/获得,该演示还使用原始图像数据阵列作为目标画布.

  • 不打折你的解决方案(这正是我的建议),但如果你做任何远程复杂的事情,这应该是最后的手段,因为它将是_slow_ (3认同)