シンプルなブログのサムネを生成するAPIを作ってみた

2024年08月27日

Blog Image

少し前に、ブログのサムネ生成ソフトを作ったのですが、Windowsでしか動かすことができないので、サムネを生成するAPIを作ろうと思います。

サムネ生成ソフトとは

サムネ生成ソフトとは、タイトルや、カラーコードを入力するだけでシンプルなサムネイルが自動で生成することができるソフトです。

Windowsバージョンでは、このようなソフトをC#で作っていました。

このソフトで生成できる画像がこちらです。

このような画像を生成することができるソフトを作っていたのですが、ソースコードをなくしてしまったので、APIを作ることにしました。

作成

Node.jsのsharpというライブラリと、bodyParser、expressを使って作成していきます。

まず、パッケージをインストールしていきます。

npm install express sharp body-parser

ここから、index.jsに書き込んでいきます。

720x420の画像サイズにしたいので、widthとheightを指定します。

const background = sharp({
  create: {
    width: 710,
    height: 420,
    channels: 4,
    background: bgColor,
  },
});

ちなみに、channels: 4 だと、画像がRGBA形式で生成されます。channels:3 の場合は、RGB、channel:1 なら、モノクロで生成されます。

次に、真ん中に四角い部分を作りたかったので、このようにしました。

const roundedRectangle = Buffer.from(`
  <svg width="710" height="420">
    <rect x="20" y="25" width="670" height="370" rx="30" ry="30" fill="${circleColor}" />
  </svg>
`);

幅を670、 高さを370に指定して、すべての角に30pxの丸みを付けています。

すごく省略していますが、最後に画像を送って終了です。

const finalImage = await background
    .composite([{ input: roundedRectangle }, { input: svgText }])
    .png()
    .toBuffer();

    res.type('png');
    res.send(finalImage);

他の部分では、最大行数や、一行当たりの文字数なども指定していますが、説明は省略します。

全体のコード(サンプル)

const sharp = require('sharp');
const express = require('express');
const app = express();

app.use(express.json());

// サムネイル作成API 
app.get('/generate-thumbnail', async (req, res) => {
    const { title, bgColor, textColor } = req.query;

    const fontSize = 30;
    const maxCharsPerLine = 21;

    const lines = [];
    while (title.length > 0) {
        lines.push(title.substring(0, maxCharsPerLine));
        title = title.substring(maxCharsPerLine);
    }

    // 背景画像の作成
    const background = sharp({
        create: {
            width: 710,
            height: 420,
            channels: 4,
            background: bgColor,
        },
    });

    // テキストをSVG形式で作成
    const svgText = Buffer.from(`
        <svg width="710" height="420">
        <style>
            text {
                font-size: ${fontSize}px;
                fill: ${textColor};
                text-anchor: middle;
                dominant-baseline: middle;
            }
        </style>
        ${lines.map((line, index) => `
            <text x="355" y="${100 + (index * (fontSize * 1.2))}">${line}</text>
        `).join('\n')}
        </svg>
    `);

    try {
        const finalImage = await background
            .composite([{ input: svgText }])
            .png()
            .toBuffer();

        res.type('png');
        res.send(finalImage);
    } catch (error) {
        console.error('Error generating thumbnail:', error);
        res.status(500).send('サムネイルの生成に失敗しました');
    }
});

使い方

使い方は簡単です。

エンドポイント

URL: https://massango.jp/generate-thumbnail

クエリパラメータ

title

サムネイルに表示するテキスト。文字列で、サムネイルに表示されるテキスト内容を指定します。

circleColor

背景の上に背景を作っています。白色から変える必要はない気がします(例: #23FFFFFF)

bgColor

サムネイルの背景色。16進数形式で指定します(例: #2589D0)

textColor

テキストの色。16進数形式で指定します(例: #000000)

リクエストの例

https://massango.jp/generate-thumbnail?title=Hello%20World&bgColor=%232589D0&circleColor=%23FFFFFF&textColor=%23000000

URLエンコードの関係で、「#」を「%23」に置き換えてください。

作成されたサムネイル

作成されたサムネはこちらです

少し文字が小さい気がしますが、まあいいでしょう。

終わりに

これで、サムネイル生成APIの説明は終わりです。サンプルコードを参考に、自分のプロジェクトでカスタマイズしたり、さらに機能を追加したりしてみてください。APIを使って簡単にサムネイルを生成できるので、ぜひ使ってみてください。

何か質問やフィードバックがあれば、お問い合わせからお願いします。