Slide 1

Slide 1 text

実録!フグ料理 #1 FROKAN#7 @Takepepe

Slide 2

Slide 2 text

About Me ■ Takefumi Yoshii / @Takepepe ■ DeNA / DeSC Healthcare ■ Frontend Engineer ■ TypeScript Meetup JP member

Slide 3

Slide 3 text

フグ料理?

Slide 4

Slide 4 text

Project Fugu

Slide 5

Slide 5 text

Project Fugu NativeApp と WebApp の差分を 埋めるため、NativeApp でしか リーチ出来なかった API を Chrome で解放するプロジェクト。 https://developers.google.com/web/updates/capabilities

Slide 6

Slide 6 text

Project Fugu Google I/O でもセッションがあり、 来たるChromeDevSummit でも 進捗共有があるそうです。 https://developer.chrome.com/devsummit/

Slide 7

Slide 7 text

Why "Fugu" ? セキュリティ・プライバシーの観点から、 NativeAPI へのアクセスには注意が必要。 ※ カメラなど特に。 フグは美味しいけど、調理次第では毒となることも。 その自戒の念を込めた名称が「Project Fugu」

Slide 8

Slide 8 text

Completely list of APIs 「Project Fugu」に含まれるAPIは、現在 80 以上ある。 既に実験的に試せる API として、巷で話題になったものもちらほら。 ■ Web Bluetooth API ■ Web Share API ■ Media Session API ■ Shape Detection API ■ Badging API ■ Get Installed Related Apps API ■ Wake Lock API ■ Writable Files API https://docs.google.com/spreadsheets/d/1de0ZYDOcafNXXwMcg4EZhT0346QM-QFvZfoD8ZffHeA/edit#gid=272423396

Slide 9

Slide 9 text

Let's Cooking ! 今日は「矩形検出」の Shape Detection API を使って、 何か作ってみた記録を紹介していきます。 ■ Web Bluetooth API ■ Web Share API ■ Media Session API ■ Shape Detection API ■ Badging API ■ Get Installed Related Apps API ■ Wake Lock API ■ Writable Files API https://docs.google.com/spreadsheets/d/1de0ZYDOcafNXXwMcg4EZhT0346QM-QFvZfoD8ZffHeA/edit#gid=272423396

Slide 10

Slide 10 text

Shape Detection API Shape Detection API で検出可能なものは 3種類。 バーコード検出、テキスト検出(光学式文字認識)および顔検出 Barcode Detection Text Detection Face Detection

Slide 11

Slide 11 text

試す前の事前準備

Slide 12

Slide 12 text

Enable to Experimental Features Shape Detection API を Chrome で 試すためには、chrome://flags で Experimental Web Platform features (実験的機能)を Enabled にする。

Slide 13

Slide 13 text

Enable to Experimental Features Shape Detection API を Chrome で 試すためには、chrome://flags で Experimental Web Platform features (実験的機能)を Enabled にする。 AndroidChrome でも 一部利用可能!

Slide 14

Slide 14 text

使い方

Slide 15

Slide 15 text

BarcodeDetector 画像要素から、バーコード文字列・矩形を複数検出(たったこれだけ!) async function detectBarcode( element: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement ) { if (!window.BarcodeDetector) return new Error('BarcodeDetector is undefined') const barcodeDetector = new window.BarcodeDetector() return await barcodeDetector.detect(element) }

Slide 16

Slide 16 text

TextDetector 画像要素から、テキスト・矩形を複数検出(たったこれだけ!) async function detectText( element: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement ) { if (!window.TextDetector) return new Error('TextDetector is undefined') const textDetector = new window.TextDetector() return await textDetector.detect(element) }

Slide 17

Slide 17 text

FaceDetector 画像要素から、顔面・矩形を複数検出(全部一緒!) async function detectFace( element: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement ) { if (!window.FaceDetector) return new Error('FaceDetector is undefined') const faceDetector = new window.FaceDetector() return await faceDetector.detect(element) }

Slide 18

Slide 18 text

検出

Slide 19

Slide 19 text

BarcodeDetector boundingBox: DOMRectReadOnly bottom: 293.48682403564453 height: 181.0986328125 left: 272.1447448730469 right: 445.8060607910156 top: 112.38819122314453 width: 173.66131591796875 x: 272.1447448730469 y: 112.38819122314453 cornerPoints: Array(4) 0: {x: 275.6146545410156, y: 112.38819122314453} 1: {x: 445.8060607910156, y: 126.80418395996094} 2: {x: 437.9911193847656, y: 293.48681640625} 3: {x: 272.1447448730469, y: 292.72515869140625} length: 4 format: "qr_code" rawValue: "https://design.dena.com/" 検出できたバーコード(ex: QR code) 画像内の矩形が取得できる(DOMRect) const barcode = await detectBarcode(element) console.log(barcode)

Slide 20

Slide 20 text

BarcodeDetector boundingBox: DOMRectReadOnly bottom: 293.48682403564453 height: 181.0986328125 left: 272.1447448730469 right: 445.8060607910156 top: 112.38819122314453 width: 173.66131591796875 x: 272.1447448730469 y: 112.38819122314453 cornerPoints: Array(4) 0: {x: 275.6146545410156, y: 112.38819122314453} 1: {x: 445.8060607910156, y: 126.80418395996094} 2: {x: 437.9911193847656, y: 293.48681640625} 3: {x: 272.1447448730469, y: 292.72515869140625} length: 4 format: "qr_code" rawValue: "https://design.dena.com/" const barcode = await detectBarcode(element) console.log(barcode) SVG ポリゴン描画などに利用できる 矩形の点座標。

Slide 21

Slide 21 text

BarcodeDetector boundingBox: DOMRectReadOnly bottom: 293.48682403564453 height: 181.0986328125 left: 272.1447448730469 right: 445.8060607910156 top: 112.38819122314453 width: 173.66131591796875 x: 272.1447448730469 y: 112.38819122314453 cornerPoints: Array(4) 0: {x: 275.6146545410156, y: 112.38819122314453} 1: {x: 445.8060607910156, y: 126.80418395996094} 2: {x: 437.9911193847656, y: 293.48681640625} 3: {x: 272.1447448730469, y: 292.72515869140625} length: 4 format: "qr_code" rawValue: "https://design.dena.com/" 検出できる Barcode Format は複数。 出典:W3C Community Group aztec, code_128, code_39, code_93, codabar, data_matrix, ean_13, ean_8, itf, pdf417, qr_code, unknown, upc_a, upc_e const barcode = await detectBarcode(element) console.log(barcode)

Slide 22

Slide 22 text

BarcodeDetector const barcode = await detectBarcode(element) console.log(barcode) boundingBox: DOMRectReadOnly bottom: 293.48682403564453 height: 181.0986328125 left: 272.1447448730469 right: 445.8060607910156 top: 112.38819122314453 width: 173.66131591796875 x: 272.1447448730469 y: 112.38819122314453 cornerPoints: Array(4) 0: {x: 275.6146545410156, y: 112.38819122314453} 1: {x: 445.8060607910156, y: 126.80418395996094} 2: {x: 437.9911193847656, y: 293.48681640625} 3: {x: 272.1447448730469, y: 292.72515869140625} length: 4 format: "qr_code" rawValue: "https://design.dena.com/" 取得できた文字列(URL等)が 「rawValue」に格納される。

Slide 23

Slide 23 text

TextDetector const text = await detectText(element) console.log(text) boundingBox: DOMRectReadOnly bottom: 293.48682403564453 height: 181.0986328125 left: 272.1447448730469 right: 445.8060607910156 top: 112.38819122314453 width: 173.66131591796875 x: 272.1447448730469 y: 112.38819122314453 cornerPoints: Array(4) 0: {x: 275.6146545410156, y: 112.38819122314453} 1: {x: 445.8060607910156, y: 126.80418395996094} 2: {x: 437.9911193847656, y: 293.48681640625} 3: {x: 272.1447448730469, y: 292.72515869140625} length: 4 rawValue: "hogehoge" 検出できる矩形情報などは、 BarcodeDetecotor と一緒。

Slide 24

Slide 24 text

TextDetector const text = await detectText(element) console.log(text) boundingBox: DOMRectReadOnly bottom: 293.48682403564453 height: 181.0986328125 left: 272.1447448730469 right: 445.8060607910156 top: 112.38819122314453 width: 173.66131591796875 x: 272.1447448730469 y: 112.38819122314453 cornerPoints: Array(4) 0: {x: 275.6146545410156, y: 112.38819122314453} 1: {x: 445.8060607910156, y: 126.80418395996094} 2: {x: 437.9911193847656, y: 293.48681640625} 3: {x: 272.1447448730469, y: 292.72515869140625} length: 4 rawValue: "hogehoge" 確認範囲では、環境差異が大きい。 矩形情報は取れても、rawValue が 取れなかったり。 日本語でも矩形だけは取れたり…

Slide 25

Slide 25 text

FaceDetector const face = await detectFace(element) console.log(face) boundingBox: DOMRectReadOnly bottom: 307 height: 176 left: 437 right: 613 top: 131 width: 176 x: 437 y: 131 landmarks: Array(3) 0: locations: Array(1) 0: {x: 491, y: 185} type: "eye" 1: locations: Array(1) 0: {x: 559, y: 185} type: "eye" 2: locations: Array(1) 0: {x: 525, y: 263} type: "mouth" 他と同様、矩形情報が複数とれる。 new FaceDetector() で引数に 速度優先・検出数上限が設定可能。

Slide 26

Slide 26 text

FaceDetector const face = await detectFace(element) console.log(face) boundingBox: DOMRectReadOnly bottom: 307 height: 176 left: 437 right: 613 top: 131 width: 176 x: 437 y: 131 landmarks: Array(3) 0: locations: Array(1) 0: {x: 491, y: 185} type: "eye" 1: locations: Array(1) 0: {x: 559, y: 185} type: "eye" 2: locations: Array(1) 0: {x: 525, y: 263} type: "mouth" 顔全体の矩形情報のほか、 目・鼻・口の頂点座標(複数)が 取得できる。

Slide 27

Slide 27 text

FaceDetector const face = await detectFace(element) console.log(face) boundingBox: DOMRectReadOnly bottom: 307 height: 176 left: 437 right: 613 top: 131 width: 176 x: 437 y: 131 landmarks: Array(3) 0: locations: Array(1) 0: {x: 491, y: 185} type: "eye" 1: locations: Array(1) 0: {x: 559, y: 185} type: "eye" 2: locations: Array(1) 0: {x: 525, y: 263} type: "mouth" Android Chrome では FaceDetecor が 利用できる判定となったが、 矩形取得が現状できなかった。 (観測範囲)

Slide 28

Slide 28 text

DEMO https://project-fugu-cooking.firebaseapp.com/

Slide 29

Slide 29 text

Recipe 顔のモザイク処理には Pixi.js を利用。 PIXI.texture に filter を適用、SVG で要素マスキング。 https://pixijs.io/pixi-filters/tools/demo/ const texture = PIXI.Texture.from(element) sprite.texture = texture sprite.filters = [new PixelateFilter((16 * offset) >> 0)] app.stage.addChild(sprite)

Slide 30

Slide 30 text

Recipe Pixi.js の filter は種類が豊富で簡単に扱える。 アイディア次第で面白いことが色々できそう! https://pixijs.io/pixi-filters/tools/demo/ const texture = PIXI.Texture.from(element) sprite.texture = texture sprite.filters = [new PixelateFilter((16 * offset) >> 0)] app.stage.addChild(sprite)

Slide 31

Slide 31 text

Recipe WebGL fragment shader による GPU レンダリングが行われるため、 canvas 上で畳み込み処理を 行うよりも高速。 https://pixijs.io/pixi-filters/tools/demo/

Slide 32

Slide 32 text

フグ料理してみた所感

Slide 33

Slide 33 text

楽しい & 楽しみ ■ 実験的機能なので、不安定なのはやむなし ■ 依存ライブラリ無しに、色々検出できるの楽しい ■ フロントエンドっぽい実装は、やはり楽しい ■ Native App ならではの機能が、今後続々!期待大

Slide 34

Slide 34 text

今後のスケジュール 2019年中には、 多くの機能が 解放される見込み。 https://www.youtube.com/watch?v=GSiUzuB-PoI&feature=youtu.be

Slide 35

Slide 35 text

本日のサンプル https://project-fugu-cooking.firebaseapp.com/ https://github.com/takefumi-yoshii/project-fugu-cooking ※ iOS Chrome で見ちゃダメだぞ!

Slide 36

Slide 36 text

ご静聴ありがとうございました