1. ホーム
  2. javascript

[解決済み] javascriptのキャンバスで画像をリサイズする (スムーズ)

2022-07-31 21:30:48

質問

canvasで画像をリサイズしようとしているのですが、どのように平滑化するのかがわかりません。 フォトショップやブラウザなどでは、いくつかのアルゴリズム (バイキュービック、バイリニアなど) が使用されていますが、これらがキャンバスに組み込まれているかどうかはわかりません。

以下は私のフィドルです。 http://jsfiddle.net/EWupT/

var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width=300
canvas.height=234
ctx.drawImage(img, 0, 0, 300, 234);
document.body.appendChild(canvas);

最初のものは通常のリサイズされた画像タグで、2番目のものはcanvasです。キャンバスの方が滑らかでないことに注目してください。どうすれば「滑らかさ」を実現できるのでしょうか?

解決方法は?

ダウンステップを使用すると、より良い結果を得ることができます。ほとんどのブラウザは はバイキュービックではなくリニア補間を使用しているようです。 を使用するようです。

( 更新 仕様に品質プロパティが追加されました。 imageSmoothingQuality というプロパティが追加されました(現在は Chrome のみで利用可能です)。

スムージングなしまたは最近傍を選択しない限り、ブラウザは画像をダウンスケールした後、常に補間します。

バイリニアは 2x2 ピクセルを使用して補間を行うのに対し、バイキュービックは 4x4 を使用するので、ステップで行うことにより、結果の画像に見られるように、バイリニア補間を使用しながらバイキュービックの結果に近いものを得ることができます。

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var img = new Image();

img.onload = function () {

    // set size proportional to image
    canvas.height = canvas.width * (img.height / img.width);

    // step 1 - resize to 50%
    var oc = document.createElement('canvas'),
        octx = oc.getContext('2d');

    oc.width = img.width * 0.5;
    oc.height = img.height * 0.5;
    octx.drawImage(img, 0, 0, oc.width, oc.height);

    // step 2
    octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5);

    // step 3, resize to final size
    ctx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5,
    0, 0, canvas.width, canvas.height);
}
img.src = "//i.imgur.com/SHo6Fub.jpg";
<img src="//i.imgur.com/SHo6Fub.jpg" width="300" height="234">
<canvas id="canvas" width=300></canvas>

リサイズの度合いにもよりますが、差が少ない場合は手順2を省略することができます。

デモでは、新しい結果が画像要素によく似ていることがわかります。