猫の手ツール

Algorithm & UI/UX

ピクセル操作によるシネマ風の色とクレジットの文字サイズ調整

本ツールは、何気ない日常の写真を「映画の終幕」へと変貌させます。単に文字を重ねるだけでなく、ブラウザの標準機能をあえて回避し、低レベルなピクセル操作を行うことで、古い映画のような独特の重厚感をクライアントサイドのみで実現しました。

このツールの入力から出力まで

現行コードの確認日:

入力
写真とエンドロールに見せる文章を入力します。
処理
画像を描いた上にクレジットの文字と暗い表現を重ねます。
出力
入力は長辺 1500px 以下に縮小し、1280×720px の JPEG(品質指定 0.9)にします。

まず確認する点:文字が流れる動画ではありません。入力した行がどこまで収まるか、最終画像の余白と文字サイズで確認します。

仕上がりの例

写真を横長にし、「FIN」の文字を重ねた映画エンディング風の例です。

加工前・加工後
左は横になった茶トラの愛猫の写真。右は暗くした横長写真の中央にFINと小さな文字を加えた画像。

加工前・加工後

左は横になった茶トラの愛猫の写真。右は暗くした横長写真の中央にFINと小さな文字を加えた画像。

掲載画像はサイトにある既存の公開作例です。保存済みの資料では運営者の愛猫の写真を使用しています。今回の確認日が、この作例を実行した日を表すわけではありません。

保存済み検証記録の条件を見る

資料の種類は「ツールの出力画像を保存した記録」です。公開作例と保存済み記録で素材や色などが異なる場合があるため、下の数値は保存済み検証記録の条件として読んでください。

記録の入力画像
800×805px (JPEG)
記録の出力画像
1280×720px (JPEG)
保存済み記録の主な操作・出力条件
画面の項目記録の値現行コードの初期値・範囲
記録で選択されていた項目シネマ—
エンドマークFIN初期値 FIN
スタッフロール (改行で調整)主演 ねこ 撮影 家族 特別協力 日なた初期値 CAST あなたの名前 DIRECTOR 猫の手貸し MUSIC 感動的なBGM
ズーム100初期値 100 / 範囲 50〜300

記録では「完成!終幕を迎える」から完成表示へ進んでいます。初期値と記録値を比べてから、効果を1項目ずつ変えると作用を確認しやすくなります。

資料ファイルの作成日は実行日として扱っていません。個別端末の処理速度や、ほかの写真に対する検出・加工の精度を測定した資料でもありません。

実装の確認箇所:src/pages/image/movie-end/index.astro。以下のコード抜粋と出力条件は、この本番実装に基づいて説明します。

仕組みを読み進めるときは、Canvas APIと画像処理(画像寸法、drawImage、画素と透明度の扱い)、メモリ管理と画像処理(画素バッファ、縮小と容量予算)が参考になります。

1. ctx.filter に頼らないピクセル操作フィルター

モダンなブラウザには ctx.filter が存在しますが、モバイルブラウザでの動作不安定さや、彩度・コントラストの微細な調整が難しいという課題があります。

本ツールでは、getImageData を使用して Canvas 上のピクセル配列(RGBA)を直接取得し、輝度(Luma)計算に基づいた独自のグレースケール変換とコントラスト補正を適用しています。これにより、単なる白黒ではない「シネマティック」なトーンを安定して再現しています。

クレジット用の縦の余白は 260px です。行数から文字サイズを求める部分を抜き出しています。

function creditsFontSize(lineCount) {
  if (lineCount <= 0) return 28;
  return lineCount * 28 * 1.5 > 260
    ? Math.floor(260 / lineCount / 1.5) : 28;
}

2. 描画領域を考慮した動的な「クレジット・スケーリング」

スタッフロール(クレジット)はユーザーによって入力される行数が異なります。フォントサイズを固定にすると、行数が多い場合に下の黒帯(レターボックス)からはみ出したり、UIに重なったりする問題が生じます。

これを解決するため、描画前に「現在の行数 × 行送り」を計算し、許容される最大描画高さを超える場合は fontSize を行数から再計算する処理を搭載しました。これにより、行数に応じて文字が小さくなります。ただし横幅の自動調整はなく、多すぎる行は判読しにくくなります。

3. サーバーレスを支える HEIC/HEIF の画像変換

このツールでは、HEICを選んだ場合はブラウザ内で別の画像形式に変換してから編集します。

そこで、ファイル形式を検知した瞬間に変換モジュールを動的インポートし、heic2any で JPEG に変換してから描画します。変換用コードやフォントの取得には通信が必要で、端末やファイルによって変換が失敗する場合があります。

出力の仕様と確認する点

入力は長辺 1500px 以下に縮小し、1280×720px の JPEG(品質指定 0.9)にします。上下に各 80px の黒帯を描きます。スタッフロールが流れる動画ではなく、1枚の静止画です。

シネマは RGB の明るさを 0.6 倍、コントラストを 1.2 倍にしてから彩度を落とします。モノクロとセピアも暗くするため、暗い写真では細部が黒くつぶれる場合があります。

エンドマークは 110px の固定文字サイズです。クレジットは改行ごとの行数で縮小しますが、行の長さは判定しません。短い行に分け、保存画像で小さくなりすぎていないか確認します。