猫の手ツール

Algorithm & UI/UX

クッキリした境界を作る「二段階描画」とレトロ配色のロジック

ただ画像を縮小するだけでは「ボケたモザイク」になってしまいます。本ツールがいかにして「ピクセルが際立つドット絵」をフロントエンドのみで生成しているか、その手法を紐解きます。

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

現行コードの確認日:

入力
写真を選び、ブロックの粗さと色の設定を調整します。
処理
小さなCanvasへ縮小してから補間を切って拡大し、矩形の画素を目立たせます。
出力
入力の長辺は 1500px 以下、出力はその処理画像の寸法の PNG です。

まず確認する点:ブロックの大きさと色数の処理を別々に見ると理解しやすくなります。細い模様は縮小時に混ざったり消えたりします。

仕上がりの例

写真を粗いドット絵風に変えた例です。

加工前・加工後
左は横になった茶トラの愛猫の写真。右は猫を大きな四角いドットで表した画像。

加工前・加工後

左は横になった茶トラの愛猫の写真。右は猫を大きな四角いドットで表した画像。

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

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

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

記録の入力画像
800×751px (JPEG)
記録の出力画像
800×751px (PNG)
保存済み記録の主な操作・出力条件
画面の項目記録の値現行コードの初期値・範囲
記録で選択されていた項目制限なし フルカラー—
ドットの粗さ (ピクセルサイズ)16初期値 16 / 範囲 2〜64

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

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

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

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

1. 「ニアレストネイバー法」によるシャープな再拡大

一般的な画像リサイズではバイリニア法などが用いられ、周囲の画素と平均化されるため境界がボケます。本ツールでは、一度 Canvas を極小サイズに縮小して情報を間引いた後、imageSmoothingEnabled = false を設定したメイン Canvas へ描き戻しています。

これにより、拡大時に補間処理が行われず、隣接するピクセルの色がそのまま維持される「ニアレストネイバー(Nearest Neighbor)」効果をブラウザ標準機能だけで実現しています。

GB 風の4色割り当てを1画素に適用する例です。誤差拡散や網点によるディザリングは行いません。

function gamePalette(r, g, b) {
  const colors = [[15,56,15], [48,98,48], [139,172,15], [155,188,15]];
  const y = r * 0.299 + g * 0.587 + b * 0.114;
  return colors[y < 64 ? 0 : y < 128 ? 1 : y < 192 ? 2 : 3];
}

2. 輝度ベースのパレットマッピング(GB風モード)

レトロ感を出すための「GB風」パレットは、単なる色被せではありません。まずピクセルのRGB値からグレースケール輝度を算出し、その輝度をあらかじめ定義した4つの階調(パレット)のいずれかに割り当てる4段階のしきい値による減色処理を行っています。

この実装により、元の写真の明暗差がドット絵の「色の濃淡」として正しく変換され、昔の携帯ゲーム機のような深みのある表現が可能になります。

3. iPhoneユーザーのための HEIC クライアントサイド変換

iPhoneの標準画像形式であるHEICは、ブラウザのCanvas APIで直接読み込めないケースが多いという課題があります。本ツールでは heic2any ライブラリを活用し、ブラウザ内で JPEG への動的変換を行っています。

これを「サーバーを介さずクライアントサイドで完結」させることで、ユーザーのプライバシーを守りつつ、HEIC を選択した場合も同じ加工へ進めるようにしています。変換の成否や処理時間は端末とファイルに依存します。

出力の仕様と確認する点

ドットサイズは保存画像に対して 2〜64px で、値を大きくするほど少ない画素に縮小します。プレビューでは表示幅に合わせてドットの大きさも換算するため、保存時と境界位置が少し異なる場合があります。

レトロ配色は RGB の各成分を 0・51・102・153・204・255 の6段階に丸めます。GB 風は輝度 64・128・192 を境界に4色へ割り当て、フルカラーは減色をしません。

入力の長辺は 1500px 以下、出力はその処理画像の寸法の PNG です。小さなドット配列そのものを低解像度ファイルとして出力する機能ではなく、拡大した見た目を保存します。