Slide 1

Slide 1 text

Cloud Functionsで Open Graph Protocolの画像 を自動生成する pixiv Inc. 森内 建太 2018.9.22

Slide 2

Slide 2 text

2 自己紹介まわり ● ピクシブ福岡オフィス アルバイト ● フロントエンドエンジニア ● なんだかんだ iOS アプリも Rails も触る ● 副業として GFTD. Fukuoka Works で Web 技術を 教えている 森建 petamoriken

Slide 3

Slide 3 text

3 pixiv chatstory ● チャット小説形式の作品が投稿 閲覧できるサービス ● iOS ネイティブアプリと PWA ● PWA は Firebase Hosting, Cloud Functions for Firebase で SSR

Slide 4

Slide 4 text

● チャット小説? ● 認知度を上げるために OGP の画像に アプリの画面を描画した 4 pixiv chatstory

Slide 5

Slide 5 text

5 Cloud Functions で画像のレンダリング

Slide 6

Slide 6 text

基本的には公式サンプルを見てください 6

Slide 7

Slide 7 text

ここではハマった項目を紹介します 7

Slide 8

Slide 8 text

フォントの問題 8

Slide 9

Slide 9 text

● 日本語フォントが入っていないので Noto Sans CJK JP を使った ● node-canvas v2.0.0-alpha にローカルファイルのフォントを読み込ませる registerFont というメソッドがある 9 フォントの問題

Slide 10

Slide 10 text

CanvasRenderingContext2D の改行問題 10

Slide 11

Slide 11 text

● fillText を使ってテキストを描画する ○ 改行文字は無視される ■ pixiv chatstory は仕様で改行文字は入らないので今回は関係ない ○ measureText で描画する前に横幅を測り、自前で改行を実装しなけらばならない ■ “一文字”ずつ切り出して measureText をしまくる 11 CanvasRenderingContext2D の改行問題

Slide 12

Slide 12 text

JavaScript の文字列の分割 12

Slide 13

Slide 13 text

JavaScript 13 const str = " " ; // [0xD842, 0xDFB7], 0x91CE, 0x5C4B str.length; // 4 // ES2015 String#[@@itarator] [...str].length; // 3 [...str]; // [" ", " ", " "]

Slide 14

Slide 14 text

JavaScript 14 const str = " "; [...str].length; // 7 [...str]; // [" ", "\u200d", " ", "\u200d", " ", "\u200d", " "] Twemoji Copyright 2018 Twitter, Inc and other contributors

Slide 15

Slide 15 text

_人人人人人人人人人_ > 一家離散の危機 <  ̄Y^Y^Y^Y^Y^Y^Y^Y ̄ 15

Slide 16

Slide 16 text

● ES2015 String#[@@iterator] はコードポイントで分割するが、これは ”一文字”ではない ● ちゃんとやるには Unicode で定義されている Grapheme Cluster アルゴリズムを使う http://unicode.org/reports/tr29/ JavaScript 実装: https://github.com/orling/grapheme-splitter ● “一文字” = 書記素(grapheme) 16 JavaScript の文字列の分割

Slide 17

Slide 17 text

● 将来的には ESNext Stage 3 Intl.Segmenter を使えばよくなる ● 書記素で分割できるのはもちろんのこと、 locale を渡すと改行すべきかどうかも判定出来 る http://unicode.org/reports/tr14/ ○ 英単語内の途中で改行されないだとか、句読点の字下げとかも考慮できる 17 JavaScript の文字列の分割(おまけ)

Slide 18

Slide 18 text

ユーザーの入力したテキストを元に いい感じの画像生成していきましょう  18 Twemoji Copyright 2018 Twitter, Inc and other contributors

Slide 19

Slide 19 text

fin. 19

Slide 20

Slide 20 text

カラー絵文字の問題(未解決) 20

Slide 21

Slide 21 text

● カラー絵文字の OpenType フォントは4種類ある ○ CBDT/CBLC: Noto Color Emoji ○ COLR/CPAL: Segoe UI Emoji ○ sbix: Apple Color Emoji ○ SVG: Twitter Color Emoji ● 詳しくは「カラー絵文字〜OpenTypeフォントの仕様を中心に〜」 https://qiita.com/496_/items/6910dd76283ba1347327 21 カラー絵文字の問題

Slide 22

Slide 22 text

● CBDT/CBLC, SVG を node-canvas に読み込ませてみたが上手く行かなかった ○ Cairo/Pango の最新バージョンに対応しないといけないっぽい ○ Cairo and Pango have to do some coordinating to get emojis working, I would try to compile the latest of both from source. Supposedly it should work but as you can see above we couldn't get it working, and I sunk a lot of time into it https://github.com/Automattic/node-canvas/issues/760#issuecomment-380205365 22 カラー絵文字の問題

Slide 23

Slide 23 text

● Twemoji には PNG があるので自分で位置調節して drawImage したらなんとか出来る ○ node-canvas の measureText が最新の canvas の仕様に則って width 以外の情 報も取れたらなんとかなりそうな気がする ○ 一旦描画してピクセル単位で解析するライブラリが一応存在する https://github.com/dy/font-measure ■ 重そう 23 カラー絵文字の問題 Twemoji Copyright 2018 Twitter, Inc and other contributors