web-dev-qa-db-ja.com

アンチエイリアスなしで画像を引き伸ばす方法

だから私は最近これに遭遇しました: http://www.nicalis.com/

そして私は気になった:より小さな画像でこの種のことをする方法はありますか?つまり、それはピクセルアートであり、各ピクセルのサイズが4倍になった画像を使用するのではなく、コードでそれらを伸ばすことはできませんか?だから私はそれを実現しようと試み始めました。

CSS、Javascript、さらにはHTMLを試しましたが、どれもうまくいきませんでした。それらはすべて非常にひどくぼやけます(このように: http://jsfiddle.net/nUVJt/2/ )。これは私の質問に私を導きます:アンチエイリアスなしでブラウザー内の画像を拡大できますか?

Canvas、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;
}

そして、それはすべての最新のブラウザーでアンチエイリアスを停止します。 IE7-8でも機能しますが、9では機能しません。残念ながら、9でそれを実行する方法はわかりません(以下に概説するキャンバスハックを除いて)。 JSを使用した場合よりもこの方法で実行する方がはるかに高速であるのは、面白いことではありません。これらの詳細は次のとおりです: https://developer.mozilla.org/en-US/docs/CSS/Image-rendering

EDIT2:これはまだ公式の仕様ではないため、あまり信頼できません。 ChromeとFFの両方がサポートを停止しているようです(上記の この記事 に従って))。これは本当に面倒です。 CSSでこれを本当に使い始めることができるようになるまでに、さらに数年待たなければならないでしょう。これは本当に残念です。

最終編集:これを行う公式の方法があります! image-renderingという新しいプロパティがあります。 CSS3仕様 にあります。サポートは super Spotty ですが、- Chromeがサポートを追加しました ですので、やがてimage-rendering: pixelated;と言うだけですべての機能が動作します。場所(yaayyエバーグリーンブラウザ!)

38
Timothy Miller

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);
        }
    }
};

http://jsfiddle.net/alnitak/LwJJR/ で作業デモ

[〜#〜] edit [〜#〜]より最適なデモは http://jsfiddle.net/alnitak/で入手できます。 j8YTe / 宛先キャンバスにも生の画像データ配列を使用します。

18
Alnitak

これをキャンバスで機能させる

var canvas = document.getElementById("canvas"),
    context = canvas.getContext('2d');
context.webkitImageSmoothingEnabled = context.imageSmoothingEnabled = context.mozImageSmoothingEnabled = context.oImageSmoothingEnabled = false;
4
Leonard Meagher

私が考えることができる唯一の方法は、キャンバスを経由することです。単に画像をキャンバスに描画してから、キャンバスを拡大縮小してみることができます-Ithinkこのようにアンチエイリアスを取得しないと思います。それでも行う場合は、描画呼び出しで画像をスケーリングするか、thatが機能しない場合は、getImageDataputImageDataを使用してスケーリングできます。 「手動」の画像

更新:最初のメソッドが機能する: http://jsfiddle.net/nUVJt/3/

1
Mark Kahn

確かではありませんが、おそらくimagedataを使用できます。この機能を試してください。

function imageToImageData(image) {
     var canvas = document.createElement("canvas");
     canvas.width = image.width;
     canvas.height = image.height;
     var ctx = canvas.getContext("2d");
     ctx.drawImage(image, 0, 0);
     return ctx.getImageData(0, 0, canvas.width, canvas.height);
}
0
Salt Hareket

いいえ。ブラウザーはそれを行いますが、スケーリングアルゴリズムを制御できません。

ただし、作成できるキャンバスベースのソリューションは確かにありますが、おそらくソースイメージからピクセルをコピーし、戦略的にキャンバスに描画する必要があります。トリッキーですが、可能です(そして遅い)。

0
Alex Wayne