Canvas#drawImage で縮小した際に綺麗に表示する幾つかの方法

  • 25
    Like
  • 0
    Comment
More than 1 year has passed since last update.

Canvas#drawImage を使ってかなり大きな画像を縮小表示すると、派手にジャギーが発生する事があります。(drawImage のデフォルトのフィルターが速度優先らしく、現状このようになってしまうとか)

antialias を効かせるか、もうちょっと綺麗に表示する方法が無いか色々と探ってみました。

  • 方法1. canvasContext.drawImage(source, sx, sy, sw, sh, tx, ty, tw, th) を使って描画する方法

    • 画像1 と 2 の Original がこれです
  • 方法2. HTML5 Rocks にあるように ratio = devicePixelRatio / backingStoreRatio を計算し、canvas のサイズ(width, height)と canvas のviewサイズ(style.width, style.height) を設定し、canvasContext.scale(rario, ratio) を実行し、displayの表現能力を活かしきる方法

    • 画像1 と 2 の backingStoreRatio がこれです (toRetina はこれの亜種です)
  • 方法3. StackOverflow にあるように、downsampling を何度か行い(1.0 → 0.5 → 0.25, ...) 滑らかにする方法

    • 画像1 と 2 の antialiasing がこれです
    • 速度とコストのトレードオフが発生します

Example

画像1
MacBookPro Retina Display
画像2
DELL の外付け Display

表示品質

このような単純な例だと、
Retina Display における表示品質は 方法2 > 方法3 > 方法1 で、
非Retina Display における表示品質は 方法3 > 方法2 > 方法1 になるようです。

jsfiddle で実際に試す事ができます。