猫の手ツール

Algorithm & UI/UX

漫画の迫力をブラウザで再現する:
集中線描画とピクセル操作の裏側

写真の中央に向かって視線を強制誘導する「集中線」。単純な線描画に見えて、リアルタイムな描画パフォーマンスと、書き出し時の「漫画らしさ」を両立させるために、幾何学計算とピクセルレベルの画像処理を組み合わせています。

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

現行コードの確認日:

入力
写真を選び、線の色・量・中央の空白と、写真の位置・ズームを調整します。
処理
中心から外側へ向かう放射状の線をCanvas上に描きます。
出力
入力は長辺 1500px 以下に縮小し、800×800px の JPEG(品質指定 0.9)を出力します。

まず確認する点:線の中心は正方形の中央に固定されています。写真をドラッグして強調したい物を中央へ合わせ、顔や文字が線で隠れないか確認します。

仕上がりの例

写真に漫画風の集中線を加えた例です。

加工前・加工後
左は口を大きく開けた茶トラの愛猫の写真。右は猫の顔に向かう黒い集中線を重ねた画像。

加工前・加工後

左は口を大きく開けた茶トラの愛猫の写真。右は猫の顔に向かう黒い集中線を重ねた画像。

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

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

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

記録の入力画像
800×751px (JPEG)
記録の出力画像
800×800px (JPEG)
保存済み記録の主な操作・出力条件
画面の項目記録の値現行コードの初期値・範囲
記録で選択されていた項目黒色、カラー—
線の多さ70初期値 70 / 範囲 10〜100
中心の広さ50初期値 50 / 範囲 10〜100
写真のズーム100初期値 100 / 範囲 50〜300

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

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

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

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

1. 極座標を用いた放射状ラインの高速レンダリング

最大 900 本の線を高い密度で描画しつつ、ユーザーの操作(スライダー調整)にリアルタイムで反応させるため、本ツールでは描画の度に乱数計算を行わない「事前生成キャッシュ戦略」を採用しています。

線の角度や長さの揺らぎをあらかじめ配列に保持し、描画ループ内では Math.cos と Math.sin を用いた座標変換のみを行うことで、計算負荷を最小限に抑えています。これにより、同じ編集中に線の角度や開始位置が変わらないようにしています。処理時間は端末によって異なります。

密度と中心余白のスライダーを描画値に変換する例です。線の中心は 800×800px の中央です。

function speedLineSettings(density, centerSize) {
  return { count: Math.floor(density / 100 * 800) + 100,
    baseInnerRadius: centerSize / 100 * 400 };
}

2. Canvasピクセル操作による「漫画調」フィルター

単に集中線を重ねるだけでなく、背景の写真を「漫画の1コマ」のように見せるため、独自の画像フィルタリング処理を実装しています。CSSの filter プロパティではなく、Canvasの ImageData を直接操作することで、保存(書き出し)時にフィルタ効果を完全に画像へ焼き付けることができます。

処理フローとしては、NTSC加重平均法によるグレースケール変換、輝度補正、そしてハイライトとシャドウを際立たせるコントラスト調整を1回のピクセルループ内で完結させ、実行速度を稼いでいます。

出力の仕様と確認する点

入力は長辺 1500px 以下に縮小し、800×800px の JPEG(品質指定 0.9)を出力します。写真の位置は動かせますが、集中線の中心は正方形の中央に固定されています。

密度 10〜100 で線は 180〜900 本です。中心余白を増やすと線の開始位置が外側へ移動します。実装は線を1つのパスにまとめて最後に stroke するため、各線の太さを個別に変えて描く処理ではありません。

漫画風は輝度の明るさを 1.2 倍、コントラストを 1.5 倍にした白黒表現です。網点や輪郭抽出は行わず、明るい部分・暗い部分が上限や下限に達して細部が消える場合があります。