imgixのRendering APIを利用してQiitaのようなOGPを作る



# imgixとは
https://www.imgix.com
このQiitaでも利用されている画像向けCDNサービスです。
画像配信だけでなく、Rendering APIを利用することによってリサイズやクロップ、文字の合成などをクエリパラメータによって指定することができます。

# imgixでOGP画像を生成しよう
imgixの文字合成機能を利用することで、タイトルに応じたOGP画像を自動生成することができます。
そう、このQiitaでもこの方法で生成されています。

imgix公式で[複数行や合成などの手法](https://docs.imgix.com/tutorials/multiline-text-overlays-typesetting-endpoint)は紹介されていますので、この記事ではQiitaのようなOGPを生成するやりかたを紹介します。

※ 詳細パラメータは異なります。

# 台紙となる画像を用意
今回はこんな感じの台紙を用意しました。
幅1200px、高さ630pxです。
![sample-ogp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89213/8537b4a2-fbb9-5575-adb9-a26546090936.png)

# 複数行挿入できるテキストエリアを作る
[txtパラメータ](https://docs.imgix.com/apis/rendering/text/txt)を利用することで画像にテキストを合成することができますが、このパラメータで指定すると複数行のテキストに対応できません。
複数行のテキストを生成するために[blendパラメータ](https://docs.imgix.com/apis/rendering/text/txt)を利用します。
blendパラメータ自体は画像に画像を重ねる効果を得ることができますが、これを利用して画像に複数行の文字を生成した画像を重ねて実現します。
まずは複数行の文字の画像を作ります。
これには[Typesetting Endpoint](https://docs.imgix.com/apis/rendering/typesetting/~text)を利用します。
`http(s)://assets.imgix.net/~text`
このエンドポイントにクエリパラメータをつけて文字だけの画像を生成することができます。

```
https://assets.imgix.net/~text?txtsize=56&w=1000&h=300&txt-align=center,middle&txt=ここに複数行の説明文が入ります。ここに複数行の説明文が入ります。
```

### フォントを設定する
デフォルトフォントのままだと、日本語が中華フォントになってしまいます。
QiitaでもOGP採用初期はこの[問題](https://qiita.com/FlameArche/items/61ffeb8350725e7f95ce)が見られました。
この回避方法はimgixのドキュメントで見つけられませんでしたが、Qiitaの生成するクエリパラメータから判明しました。
それは、「`txtfont=Hiragino Sans W5`」と指定することです。
[imgixのドキュメント](https://docs.imgix.com/apis/rendering/text/txt-font)のフォントリストには入ってないのだが・・・？

※ 実際に利用する際にはURLエンコードを行ってください。（例）「txtfont=Hiragino%20Sans%20W5」
※ フォントウェイトを変更する際はW5を適宜変更してみてください。

### ここまでの合成
URLをベタッと貼ると見にくいので今回はPHPのパラメータで紹介します。

```php
$blend = "https://assets.imgix.net/~text?txtsize=56&w=1000&h=300&txt-align=center,middle&txtfont=Hiragino%20Sans%20W6&txt=ここに複数行の説明文が入ります。ここに複数行の説明文が入ります。";
$parameter = [
    "blend-y" => 190,
    "blend-mode" => "normal",
    "blend" => $blend,
    "w" => 1200,
    "h" => 630,
    "dpr" => 1,
    "q" => 80
];
```
![sample-ogp1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89213/5e7246e0-1ccf-fe26-3f70-80795d602b04.jpeg)


# ユーザー名を挿入する
blendと同様の処理を行うことで実現できそうですが、blendは重複して利用することができません。
そこでwatermarkこと[warkパラメータ](https://docs.imgix.com/apis/rendering/watermark)を利用することで2つの文字を重ねることができます。
watermarkは名前の通りの機能を提供しているのですが、先程のblendと同様、Typesetting Endpointの画像を重ねることで文字合成が可能です。

```
https://assets.imgix.net/~text?txtsize=30&txtfont=Hiragino%20Sans%20W5&txt=@kubotak
```

### ここまでの合成
```php
$blend = "https://assets.imgix.net/~text?txtsize=56&w=1000&h=300&txt-align=center,middle&txtfont=Hiragino%20Sans%20W6&txt=ここに複数行の説明文が入ります。ここに複数行の説明文が入ります。";
$mark = "https://assets.imgix.net/~text?txtsize=30&txtfont=Hiragino%20Sans%20W5&txt=@kubotak";
$parameter = [
    "blend-y" => 190,
    "blend-mode" => "normal",
    "blend" => $blend,
    "mark-align" => "bottom,right",
    "mark-pad" => 50,
    "mark" => $mark,
    "w" => 1200,
    "h" => 630,
    "dpr" => 1,
    "q" => 80
];
```

# 全体のおさらい
![OGP説明.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89213/99f5ac4e-426e-9548-d290-837600e4e56d.png)

- blendで複数行文字を合成
  - 日本語フォントは「`txtfont=Hiragino Sans W5`」
- watermarkで投稿者名を合成

### 完成
![sample-ogp2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89213/003cfdf7-df47-d4af-aaf9-3ebd38be0f4f.jpeg)

imgixを利用することで簡単にOGP画像を生成することができました。
[cloudinary](https://cloudinary.com)にも同様の機能があるみたいで、[zenn](https://zenn.dev)ではそちらが利用されているみたいです。
外部サービスをうまく利用してOGPを手作業で作る手間を省きましょう！

# おまけ
### FacebookOGPで表示されない
原因の特定ができていないのですが、imgixによる自動生成のOGPはなぜかFacebookのシェアで正しく画像として認識されませんでした。
これを回避するには独自のエンドポイントを作って内部的にimgixで生成した画像を返却するようにすると良いでしょう。
（URLがクエリパラメータによって長くなっていることが原因？）