みかづきブログ その3

3ヶ月つづけてみました。

CanvasのdrawImageで画像の縮小を綺麗に行なう為のClassをつくりました。 😎

CanvasのdrawImageで画像の縮小を行なう際に、一気にサイズを小さくするとジャギーがひどいことになってしまうことがあったので、段階的に小さくしていくためのClassをつくりました。

インターフェイスとしては、

var obj = SmoothResize.resize(img, zoom);

という感じで、画像と倍率を渡すと、オブジェクトが同期的に返ってくる感じとなっており、
オブジェクトの中身は、

{
  elm    : _elm, // canvas
  width  : _elm.width, // canvasの幅
  height : _elm.height // canvasの高さ
};

という感じです。
いまとなっては、canvasをそのまま返しても良かった気がしています。


Javascript

  // 画像をギザつかせずにリサイズする
  class SmoothResize {
    // 変数節約のために引数を実際よりも多めに取る
    static resize(img, zoom, _elm, _ctx, _elm2, _elm2Ctx, _zoom) {
      _elm      = doc.createElement("canvas");
      _elm2     = doc.createElement("canvas");
      _ctx      = _elm.getContext("2d");
      _elm2Ctx  = _elm2.getContext("2d");
      _zoom     = 1;

      if (zoom >= 1) {
        _elm.width  = img.width  * zoom;
        _elm.height = img.height * zoom;
        _ctx.drawImage(img, 0, 0, _elm.width, _elm.height);
      } else {
        _elm.width  = img.width;
        _elm.height = img.height;
        _ctx.drawImage(img, 0, 0);

        while (_zoom > zoom) {
          _zoom /= 2;
            
          if (_zoom / 2 < zoom) {
            _zoom = zoom;
          }
            
          _elm2.width  = img.width  * _zoom;
          _elm2.height = img.height * _zoom;
          _elm2Ctx.drawImage(_elm, 0, 0, _elm2.width, _elm2.height);

          _elm.width  = _elm2.width;
          _elm.height = _elm2.height;
          _ctx.drawImage(_elm2, 0, 0, _elm.width, _elm.height);
        }

        _elm.width  = img.width  * zoom;
        _elm.height = img.height * zoom;
        _ctx.drawImage(_elm2, 0, 0, _elm.width, _elm.height);
      }

      return {
        elm    : _elm,
        width  : _elm.width,
        height : _elm.height
      };
    }
  }

変数を節約するところ以外はかなり愚直に書きました。


DEMO

左が普通に縮小したとき、右が段階的に縮小した時です。
若干きれいに縮小できています。

JavaScript
  var img = new Image(),
      zoom = 0.05;
  
  img.onload = () => {
    (() => {
      // 普通に縮小
      var canvas = document.getElementById("canvas"),
          ctx = canvas.getContext("2d");
      
      canvas.width = img.width * zoom;
      canvas.height = img.height * zoom;
      ctx.drawImage(img, 0, 0, img.width * zoom, img.height * zoom);
    })();
      
    (() => {
     // 段階的に縮小
      var obj = SmoothResize.resize(img, zoom);
      
      doc.body.appendChild(obj.elm);
    })();
  };

  img.src = "https://dl.dropboxusercontent.com/u/325592/IMG_0029.JPG";