Webブラウザ上でリアルタイムにぼかしを加えたい

 

自己紹介

初めましての人は初めまして、そうでない人はこんばんは。HTMLファイ部のポロです。

この記事はなに?

アドベントカレンダー9日目の記事です。

この記事ではWebブラウザ上でリアルタイムにぼかしを加えるにはどんな方法があるかを書きます。

(当初の予定では「運の上げかた」という自己啓発書に乗ってそうなスピリチュアルな題目で書くつもりでしたが、 書くべき内容が多すぎて纏まらなかったのでまたの機会に書きます)

やりたいこと

ぼかしから徐々にピントが合っていく様子をリアルタイムに表現したい

f:id:s_gozaru:20161210001148p:plainf:id:s_gozaru:20161210001150p:plain

まず思ったこと

SVGやCSSのfilter処理で瞬殺できそう 😏

しかし実際は

Microsoft Edgeくんに謎の設定項目があるため、
ユーザに設定弄ってもらわないとFilterが効かない。

→OMG!

本題

Edgeや古いブラウザでも動く上手いぼかしの方法がないか、いくつかの手法を試していきました

  • stackblur
  • text-shadow🌚
  • canvas拡大🔎
  • 画像クロスフェード🌅

片っ端から紹介していきます。

(順番から察してもらえると思いますが、結果的に画像クロスフェード🌅が一番実用的でした)

stackblur

デモを見た感じ、早いしいい感じにもボケるなと思って使ってみました。

f:id:s_gozaru:20161209234636p:plain

しかし使ってみたところ、ぼかしというより滲んだ感じになってしまいました。

  • 利点:軽くて速い
  • 弱点:滲んだ感じになり、妙な色が紛れる。

text-shadow🌚

CSSのtextshadowの影だけを取り出す技です。

本体を画面外に追いやり、影をだけを取り出して使います。

text-shadow: 9999px 0 10px #fff;
transform: translateX(-9999px);

みたいな感じに使います。

  • 利点:何も準備せずにほぼcssだけで完結する、ちゃんとgaussianなボケかたをする
  • 弱点:テキストしかぼかせない

canvas拡大🔎

小さいキャンバスに描画してキャンバスを拡大する技です。

  • 利点:軽い、簡単
  • 弱点:ぼかし半径を大きくするほど、情報源の画素が減るので、荒っぽい感じになる

ぼかし半径を大きくするとかなり荒っぽい感じになるので、canvas拡大を何パターンか行い半透明で重ねると少しマシになります。しかしそれでも荒っぽさが目立つのでぼかし半径が大きいと弱いです。

imagedataをごりごりする🐗

canvasのimagedataを気合でごりごり操作してgaussianぼかしを再現する技

まじめにgaussianぼかしするライブラリはいくつかあるので、それを使うと素早く試せます

  • 利点:ちゃんと望んだ表現ができる
  • 欠点:処理がむちゃくちゃ重い。

画像クロスフェード🌅

ぼけた画像とぼけてない画像をクロスフェードする技

f:id:s_gozaru:20161210001148p:plainf:id:s_gozaru:20161210001150p:plain

  • 利点:原理的に最初と最後は理想と一致してる
  • 欠点:通信量が増える。

結局ここに落ち着いたという感じがあります。

軽さ・表現力ともに非常に良い感じでした。

 

ただ2枚でクロスフェードすると

f:id:s_gozaru:20161210001711p:plain 

のように途中ではっきりと輪郭が見えてしまうので、

つなぎになる画像をもう一枚くらい足すと良い塩梅になります。

 

 

最後に

今回検証を行うにあたり、様々な方にアドバイスいただきました。感謝!