みかづきブログ その3

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

Canvasをつかって画像をぼかす習作 #2

http://kimizuka.hatenablog.com/entry/2015/10/10/185955kimizuka.hatenablog.com

前回canvasで画像をぼかす習作をつくりました が、今回はDOMを渡すとbackground-imageに設定されている画像をぼかしてbackground-imageを差し替えるという習作をつくってみました。

background-position とか background-size が便利なので背景画像のまま使いたい場合が結構ある気がするので、こちらのほうが使い勝手がいい気がします。
内部的には、

  1. canvasをつかって画像をぼかす
  2. 加工後の画像をbase64化
  3. 元のDOMの背景画像に設定

といったことを行っています。


DEMO


JavaScript

  (function canvasBlur(win, doc, elm) {
    var body   = doc.body,
        img    = new Image(),
        canvas = document.createElement("canvas"),
        ctx    = canvas.getContext("2d"),
        imgData, data;
    
    img.onload = function() {
      var WIDTH   = this.width / 4,
          HEIGHT  = this.height / 4,
          LEVEL   = 3,
          posList = [],
          r, g, b, count;

      canvas.width  = WIDTH;
      canvas.height = HEIGHT;
      canvas.style.cssText += "; width: " + WIDTH * 2 + "px; heihgt: " + HEIGHT * 2 + "px;";

      ctx.drawImage(this, 0, 0, WIDTH, HEIGHT);

      imgData = ctx.getImageData(0, 0, WIDTH,  HEIGHT);
      data    = imgData.data;

      for (var i = 0, length = data.length; i < length; i += 4) {
        count   = 0;
        r       = 0;
        g       = 0;
        b       = 0;

        for (var j = 0, jLength = LEVEL * LEVEL; j < jLength; ++j) {
          posList[j] = i + (4 * ((j / LEVEL | 0) - (LEVEL / 2 | 0))) * WIDTH + (4 * (j % LEVEL) - (LEVEL - 1) * 2);
        }

        _blur(posList, length);
      }
        
      ctx.putImageData(imgData, 0, 0);
      elm.style["background-image"] = "url(" + canvas.toDataURL("image/png") + ")";

        
      function _blur(arr, length) {
        for (var k = 0, kLength = arr.length; k < kLength; ++k) {
          if (0 <= arr[k] && arr[k] < length) {
            ++count;

            r += data[arr[k] + 0];
            g += data[arr[k] + 1];
            b += data[arr[k] + 2];
          }
        }

        data[i + 0] = r / count;
        data[i + 1] = g / count;
        data[i + 2] = b / count;
      }
    };
    
    img.src = doc.defaultView.getComputedStyle(elm, null)["background-image"].replace(/^url\(/, "").replace(/\)$/, "").replace(/'|"/g, "");
    
  })(this, document, document.body);

次回は左右がつながってしまっている問題を解決したいと思います。