猫の手ツール

Coordinate Logic & Canvas Optimization

座標スケーリングとピクセル抽出の最適化手法

ブラウザ上で「画像から色を抜く」というシンプルな操作。その裏側では、表示上の座標を縮小した処理画像の座標へ変換し、その位置の画素を取り出しています。

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

現行コードの確認日:

入力
写真を選び、色を知りたい場所をクリックまたはタップします。
処理
画面座標を処理画像の座標へ換算し、getImageDataでその位置の1画素のRGBを読みます。
出力
出力は色見本と HEX・RGB のテキストです。

まず確認する点:長辺2000px以下の縮小やJPEG化の影響があり、元ファイルの画素と同一とは限りません。境界の近くは数回タップして違いを比べます。

仕上がりの例

猫の写真で選んだ位置から、色コードを取り出した表示例です。

元画像・抽出結果
左は緑のかぶりものを着けた愛猫の写真。右は選んだ色の見本とHEX・RGBの色コード。

元画像・抽出結果

左は緑のかぶりものを着けた愛猫の写真。右は選んだ色の見本とHEX・RGBの色コード。

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

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

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

記録の入力画像
800×1066px (JPEG)
記録の画面キャプチャ
536×134px (PNG)
保存済み記録の主な操作・出力条件
画面の項目記録の値現行コードの初期値・範囲
記録のHEX / RGB#674E38 / 103, 78, 56—

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

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

仕組みを読み進めるときは、イベントリスナーの基礎(タップやドラッグから描画へつなぐ流れ)、Canvas APIと画像処理(画像寸法、drawImage、画素と透明度の扱い)が参考になります。

1. 解像度に依存しない動的座標マッピング

このツールの核心は、ユーザーが画面上で「タップした場所」を、Canvas内の「実際のピクセル座標」に変換するアルゴリズムです。ブラウザ上の表示サイズ(CSSピクセル)はデバイスによって様々ですが、抽出元となる画像データは4Kを超えることもあります。

メリット: 表示上のサイズ(BoundingClientRect)と、Canvas自体の解像度(Width/Height)の比率を動的に算出することで、どのデバイスでも「タップした場所の色」を処理用 Canvas の1画素から取得します。元ファイルの1画素と必ず一致するという意味ではありません。

描画済みの ctx の1画素から HEX を作る例です。x・y は Canvas の範囲内の整数を渡します。

function pickHex(ctx, x, y) {
  const rgba = ctx.getImageData(x, y, 1, 1).data;
  return '#' + Array.from(rgba.slice(0, 3))
    .map(value => value.toString(16).padStart(2, '0')).join('').toUpperCase();
}

2. willReadFrequently によるピクセル解析の高速化

このツールでは、Canvasのレンダリングコンテキストを取得する際に willReadFrequently: true というオプションを有効にしています。これは、比較的新しいブラウザで導入されたパフォーマンス最適化のためのフラグです。

メリット: willReadFrequently は、画素を繰り返し読む用途であることをコンテキスト作成時に指定するオプションです。これは読み取りの多い用途をブラウザに伝えるヒントであり、速度の保証ではありません。このツールの抽出操作はクリックまたはタップです。

3. モバイル環境を保護する「解像度ガードレール」設計

最新スマホの写真は5000pxを超えることもありますが、そのまま Canvas に描くとメモリ使用量が増えます。本ツールでは、読み込み時にアスペクト比を維持したまま、処理に最適な上限解像度へスケーリングするガードレールを設けています。

メリット: 長辺を 2000px 以下に縮小して読み取り対象を減らします。HEIC はブラウザ内で JPEG に変換しますが、変換・読み込みの成功は形式や端末によって異なります。

出力の仕様と確認する点

色はタップした位置の1画素から取得します。周辺を平均する機能や、押したまま連続して追従する処理はありません。細い境界を選ぶ場合は、近くを数回タップして違いを比べます。

大きい画像は長辺 2000px 以下に縮小して JPEG(品質指定 0.9)を作る経路を通るため、縮小補間や圧縮によって元ファイルの RGB と変わる場合があります。印刷用の測色器やカラープロファイルの解析ではありません。

出力は色見本と HEX・RGB のテキストです。アルファ値は表示しません。コピーが使えない環境では出力欄の文字を選択してコピーできます。