Algorithm & UI/UX
ピクセル等価処理による「シネマティック」の再現と
動的なクレジット・スケーリング
本ツールは、何気ない日常の写真を「映画の終幕」へと変貌させます。単に文字を重ねるだけでなく、ブラウザの標準機能をあえて回避し、低レベルなピクセル操作を行うことで、古い映画のような独特の重厚感をクライアントサイドのみで実現しました。
1. `ctx.filter` に頼らない、高精度なピクセル操作フィルター
モダンなブラウザには ctx.filter が存在しますが、モバイルブラウザでの動作不安定さや、彩度・コントラストの微細な調整が難しいという課題があります。
本ツールでは、getImageData を使用して Canvas 上のピクセル配列(RGBA)を直接取得し、輝度(Luma)計算に基づいた独自のグレースケール変換とコントラスト補正を適用しています。これにより、単なる白黒ではない「シネマティック」なトーンを安定して再現しています。
// ピクセル等価処理によるフィルター適用ロジック
const imgData = ctx.getImageData(0, 0, width, height);
const data = imgData.data;
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i+1];
const b = data[i+2];
// 輝度の算出(映画的な質感を出すための重み付け)
// ここに独自の輝度計算アルゴリズムが入ります
let luma = (r * WEIGHT_R + g * WEIGHT_G + b * WEIGHT_B);
if (config.filter === 'bw') {
// 明るさとコントラストを同時に調整
luma = luma * // 独自の露出調整値;
const contrast = // 独自のコントラスト係数;
luma = (luma - 128) * contrast + 128;
data[i] = data[i+1] = data[i+2] = Math.max(0, Math.min(255, luma));
}
// セピアやシネマティックも同様のRGB演算で実装
}
ctx.putImageData(imgData, 0, 0); 2. 描画領域を考慮した動的な「クレジット・スケーリング」
スタッフロール(クレジット)はユーザーによって入力される行数が異なります。フォントサイズを固定にすると、行数が多い場合に下の黒帯(レターボックス)からはみ出したり、UIに重なったりする問題が生じます。
これを解決するため、描画前に「現在の行数 × 行送り」を計算し、許容される最大描画高さを超える場合は fontSize を再帰的、あるいは動的に縮小するアルゴリズムを搭載しました。これにより、常に美しいレイアウトが保たれます。
// テキストの自動スケーリングロジック
const lines = text.split('\n');
let fontSize = // デフォルトのベースサイズ;
let lineHeight = fontSize * // 行送り係数;
const maxAllowedHeight = (CanvasHeight - LetterboxHeight) - startY;
// 領域に収まるまでフォントサイズを調整
if (lines.length * lineHeight > maxAllowedHeight) {
// 領域内に収めるための最小限のサイズを動的に算出
fontSize = Math.floor((maxAllowedHeight / lines.length) / // チューニング係数);
lineHeight = fontSize * // 行送り係数;
}
ctx.font = `${fontSize}px "Noto Serif JP"`;
// 各行の描画処理へ... 3. サーバーレスを支える HEIC/HEIF の動的トランスパイル
iPhoneの写真は多くの場合 HEIC 形式ですが、Canvas はこれを直接描画できません。しかし、プライバシー重視の観点からサーバー側での変換は避けたい。
そこで、ファイル形式を検知した瞬間に変換モジュールを動的インポートし、クライアントサイドの Web Worker 上で JPEG/PNG への変換を完了させる設計にしました。これにより、ユーザー体験を損なうことなく、強力なプライバシー保護と互換性を両立させています。
Developer's Note
このツールで一番苦労したのは、実は「フォントの質感」です。
Webフォント(Noto Serif JP)を使用していますが、Canvasにそのまま描画するとデジタルの冷たさが出てしまいます。そこで、文字の背後に「ごくわずかな発光(ShadowBlur)」と、画面全体に「絶妙な透過度のグラデーション」を重ねることで、スクリーンに投影されているかのような奥行きを演出しました。
「ネタ画像」を作るツールではありますが、その裏側にある技術は「本物の映画」へのリスペクトを込めて実装しています。ぜひ、日常の些細な瞬間をドラマチックに締めくくってみてください。