1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

どんな写真でもエヴァ風文字を付けて、都内某所みたいにしてくれるサービスを作った話。

1
Posted at

はじめに

どうも、趣味でデータ分析している猫背なエンジニアです。

皆さんはアニメ『エヴァンゲリオン』のあの極太でスタイリッシュな明朝体のテロップや庵野監督手がける「シン」系映画等でよく見る「都内某所」のテロップを見たことがあるでしょうか?

あの独特の緊迫感とインパクト。自分の写真にもあの文字を載せてみたい……!と思い、
今回はブラウザだけで完結するエヴァ風文字ジェネレータを作ってみました。
これで、どこでも好きな写真を創作できます(笑)

サーバーサイドの処理は一切なし!HTMLとJavaScript(Canvas)だけでサクッと実装したので、そのコードの全貌とポイントを解説します。

完成品

画像をアップロードし、好きな文字を入力して「生成」ボタンを押すだけで、写真の下部にあの「エヴァ風/都内某所風」の文字が合成された画像が生成されます。

ソースコード

今回作成したコードの全量がこちらです。1つのHTMLファイルにまとまっているので、ローカルに保存すればすぐに動かせます。

evagenerator
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>エヴァ風文字ジェネレータ</title>

<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+JP:wght@900&display=swap" rel="stylesheet">

<style>
  body {
    text-align: center;
    background: #050505;
    color: #fff;
    font-family: 'Noto Serif JP', serif;
  }
  input, button {
    margin: 10px;
    padding: 10px;
    background: #000;
    border: 1px solid #333;
    color: #fff;
  }
  canvas {
    border: 1px solid #ccc;
    margin-top: 10px;
  }
</style>
</head>
<body>

<h2>エヴァ風文字ジェネレータ</h2>

<input type="file" id="imageInput"><br><br>
<input type="text" id="textInput" placeholder="文字を入力"><br><br>
<button onclick="draw()">生成</button>

<br>
<canvas id="canvas"></canvas>

<script>
function draw() {
    const file = document.getElementById('imageInput').files[0];
    const text = document.getElementById('textInput').value;

    // 画像と文字が両方揃っていない場合は処理を中断
    if (!file || !text) return;

    const img = new Image();
    const reader = new FileReader();

    // ファイルを読み込んだら画像のsrcにセット
    reader.onload = function(e) {
        img.src = e.target.result;
    };

    // 画像の読み込みが完了したらCanvasへの描画を開始
    img.onload = function() {
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');

        // キャンバスのサイズを元の画像のサイズに合わせる
        canvas.width = img.width;
        canvas.height = img.height;

        // まず元の背景画像を描画
        ctx.drawImage(img, 0, 0);

        let fontSize = 60;
        ctx.font = `bold ${fontSize}px serif`;

        // 文字幅取得
        let textWidth = ctx.measureText(text).width;

        // 最大幅(画面の横幅に対して90%までに収める)
        const maxWidth = canvas.width * 0.9;

        // 【こだわり1】はみ出る場合はフォントサイズを自動で縮小
        while (textWidth > maxWidth) {
            fontSize -= 2;
            ctx.font = `bold ${fontSize}px serif`;
            textWidth = ctx.measureText(text).width;
        }

        ctx.textAlign = "center";
        ctx.textBaseline = "middle";

        ctx.save();
        
        // 描画の基準点を画像の下部(88%の位置)に移動
        ctx.translate(canvas.width / 2, canvas.height * 0.88);

        // 【こだわり2】横に0.7倍に圧縮して「長体」を表現
        ctx.scale(0.7, 1);

        ctx.fillStyle = "white";
        ctx.fillText(text, 0, 0);

        ctx.restore();
    };

    // 画像ファイルをData URLとして読み込む
    reader.readAsDataURL(file);
}
</script>

</body>
</html>

こだわり&解説ポイント

■ 極太明朝体の導入
エヴァ風といえば「マティスEB」というフォントが有名ですが、今回は誰でも無料でWeb上で再現できるようにGoogle Fontsの「Noto Serif JP (Weight: 900)」を採用しました。この極太明朝を使うだけで一気にそれっぽい雰囲気が出ます。

■ はみ出し防止のフォント自動縮小
ユーザーが長い文字を入力した際、画像からはみ出してしまっては台無しです。
そこで、ctx.measureText(text).width で文字の横幅を計算し、画像の横幅の90%を超えている場合は、収まるまでフォントサイズをループで小さくしていく処理を入れました。

while (textWidth > maxWidth) {
    fontSize -= 2;
    ctx.font = `bold ${fontSize}px serif`;
    textWidth = ctx.measureText(text).width;
}

■ Canvasのスケール機能による「長体」の表現
ここが一番のこだわりです!
エヴァのテロップや「都内某所」の文字は、通常のフォントをそのまま打っただけではなく、少し横に潰したような文字になっています。
これをCanvasで表現するために ctx.scale(0.7, 1); を使っています。文字の横幅だけを0.7倍に圧縮することで、一気に公式のテロップに近い緊迫感が生まれました。

さいごに

HTMLとJavaScriptだけで、バックエンド不要の画像合成ツールが簡単に作れました。
今回は文字の「長体」と「極太フォント」に絞りましたが、さらに文字の周りに黒い縁取りをつけたり、背景を自動でモノトーンに加工したりすると、より本物っぽくなると思います。

みなさんもお気に入りの画像で「都内某所」ごっこを楽しんでみてください!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?