Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

WebAssembly text format で画像処理を書くぞ

6,066 views

Published on

UIT#2 怠けるために努力を惜しまない プロのフロントエンドエンジニアたち

Published in: Engineering
  • Be the first to comment

WebAssembly text format で画像処理を書くぞ

  1. 1. WebAssembly text format で画像処理を書くぞ 2018.3.8 @UIT#2
  2. 2. @kawasako3 かわさこ LINE株式会社 UIT室 Front-end Standardization チーム 開発者がLINE Platformならではの問題や手間を意識せずに シームレスに開発を行える環境を社内外に提供すること 要するに 開発基盤づくりとか イベント企画とか 去年まではNEWSサービス開発やっていた 趣味はボードゲームとか
  3. 3. #divisionfm @kitak氏とpodcastをゆるゆるやっています
  4. 4. 今日のお題
  5. 5. …の前に WebAssembly text format っ て何? wasmってなんかEmscriptenとかでC言語からコンパイルするんじゃないの?
  6. 6. 人間がWebAssemblyを読んだり編集するための wasmバイナリ形式のテキスト表現 例えば関数はこんな風に書ける (func (param i32) (param i32) (result i32) …) clang > wasm binary > wast の変換も可能
  7. 7. きっとすごいはやいんだろうな (想像) 普段のWeb開発では使わないけど ブラウザで画像とか映像処理したら楽しそう
  8. 8. 改めて今日のお題
  9. 9. PSなしで背景付きの画像を 透過したい
  10. 10. というのが 意外と面倒くさい
  11. 11. 単色塗りつぶし
  12. 12. まあこうなる
  13. 13. 近い色を塗りつぶし
  14. 14. さっきよりはきれい
  15. 15. 境界をぼかす
  16. 16. きれい
  17. 17. ちゃんとやると 結構色々やらないといけない
  18. 18. 自動選択ツールっぽいものを Webで実装するぞ (せっかくだからWebAssemblyを使ってみよう)
  19. 19. 画像データのおさらい [255, 255, 255, 255, 0, 0, 0, 255, ..] 1px #ffffff 透明度100% 1px #000000 透明度100% 画像データは一次元配列で表せる (Uint8ClampedArray) 1byte毎にピクセルのRGBA情報が入っている
  20. 20. 画像データのおさらい ■■■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■■■ Width * 4 (1px 4byte) H 18番目 0番目 横幅18pxの画像データ
  21. 21. 隣接ピクセルだけを どう処理するか
  22. 22. Flood-fill ペイントのバケツツール等で 使われているアルゴリズム
  23. 23. Flood-fill 選択されたピクセル■から処理を始める ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ 境界線
  24. 24. Flood-fill 隣り合うピクセル■が同一色であるかどうか調べる ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■
  25. 25. Flood-fill 同色だったピクセルを起点に同じ処理を繰り返す ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■
  26. 26. Flood-fill 違う色のピクセル□はそれ以上処理しない ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■
  27. 27. Flood-fill 繰り返せる限り処理する ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■
  28. 28. Flood-fill 繰り返せる限り処理する ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■
  29. 29. Flood-fill 繰り返せる限り処理する ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■
  30. 30. Flood-fill 塗りつぶし完了 ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■
  31. 31. とりあえずJSで書く
  32. 32. 愚直に書くとこうなる 再帰的に処理する
  33. 33. –Google Chrome “Uncaught RangeError: Maximum call stack size exceeded”
  34. 34. 640*480の画像でも 最大307200回ループする
  35. 35. Flood-fill take2 周囲のピクセル■■■■をQueueに詰める ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ Queue: ■■■■
  36. 36. Flood-fill take2 Queueからひとつだけ■取り出して処理する ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ Queue: ■■■
  37. 37. Flood-fill take2 Queueに周囲のピクセル■■■を格納する Queue: ■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■
  38. 38. Flood-fill take2 Queue: ■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ ■■■■■■■■■■■□■■■■■■ Queueからひとつだけ■取り出して処理する
  39. 39. わかったこと
  40. 40. あっ すごいはやい
  41. 41. WebAssembly text format で画像処理を書くぞ 2018.3.8 @UIT#2 企画倒れ
  42. 42. うるせえ オーバーエンジニアリング だ
  43. 43. オラァ!セイヤ!! (気合いで書いた)
  44. 44. • 直接扱えるデータは64bitまでの数値だけ • ADD, SUB, MUL, DIV とbit演算で頑張る • メモリは線形メモリひとつで頑張る • wat2wasmでコンパイルして頑張る 文法はたぶんここを見て頑張るしかない https://github.com/WebAssembly/spec/blob/master/interpreter/README.md#s-expression-syntax 抑えておきたいところ
  45. 45. Wast文法をちょっと解説 (スタックマシンについて) これはどちらも return a + b;
  46. 46. Wast文法をちょっと解説 (local変数について) var i = 1
  47. 47. Wast文法をちょっと解説 (if文について) if (1 > 0) { ... } else { ... }
  48. 48. Wast文法をちょっと解説 (loop文について) for (var i = 0; i < len; i++) { ... } br_ifはifを満たせばbreakするという意味なので jsと逆になるところに注意
  49. 49. Arrayを扱うには? WebAssembly.Memoryを利用する JSからはTypedArrayとして見えるので 普通に操作できる
  50. 50. Arrayを扱うには? Wasm側からメモリの0番目に読み書きする場合
  51. 51. それはそうと 結局どうだったのか
  52. 52. おー すごいはやい
  53. 53. 大きな画像でやると顕著 wasm: 299ms - js: 909ms
  54. 54. 応用してみる
  55. 55. リアルタイム画像処理デモ
  56. 56. • JS思ったよりはやい • Wastを書くのはそこまで大変じゃない • 適材適所 純粋な計算処理はJSより3倍早い • 色々できることはありそう!アイデアがあ れば懇親会で是非話しましょう! もっと詳しく知りたければMDNがおすすめ 結論
  57. 57. ありがとうございました!

×