Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cloud FunctionsでOpen Graph Protocolの画像を自動生成する

森建
September 22, 2018

Cloud FunctionsでOpen Graph Protocolの画像を自動生成する

FUKUOKA Engineers Day 2018 ~Autumn~

森建

September 22, 2018
Tweet

More Decks by 森建

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  8. フォントの問題
    8

    View Slide

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

    View Slide

  10. CanvasRenderingContext2D の改行問題
    10

    View Slide

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

    View Slide

  12. JavaScript の文字列の分割
    12

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  17. ● 将来的には ESNext Stage 3 Intl.Segmenter を使えばよくなる
    ● 書記素で分割できるのはもちろんのこと、
    locale を渡すと改行すべきかどうかも判定出来

    http://unicode.org/reports/tr14/
    ○ 英単語内の途中で改行されないだとか、句読点の字下げとかも考慮できる
    17
    JavaScript の文字列の分割(おまけ)

    View Slide

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

    View Slide

  19. fin.
    19

    View Slide

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

    View Slide

  21. ● カラー絵文字の 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
    カラー絵文字の問題

    View Slide

  22. ● 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
    カラー絵文字の問題

    View Slide

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

    View Slide