猫の手ツール

Algorithm & UI/UX

マイナンバー写真生成の仕組み:CSSガイドとCanvas配置

マイナンバー用の写真を切り抜き、Web 用の1枚または L判用の4枚配置に変換するツールです。顔の位置は目安のガイドに手動で合わせます。ここでは画面上の補助線と出力データの関係を説明します。

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

現行コードの確認日:

入力
写真を選び、申請用の枠に合わせて位置とズームを調整します。
処理
写真の一部を規格比率のCanvasへ描き、JPEGへ保存します。
出力
Web 用は 700×900px に切り抜いた写真1枚の JPEG(品質指定 0.85)、印刷用は 1051×1500px のシートに 413×531px を2列×2行で配置した JPEG(品質指定 0.95)です。

まず確認する点:背景の適否や本人確認をAIで審査する機能ではありません。完成画像と申請先の要件を照合します。

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

仕組みを読み進めるときは、Canvas APIと画像処理(画像寸法、drawImage、画素と透明度の扱い)、File APIとObject URL(選んだ画像の読み込みとBlob URLの解放)が参考になります。

1. CSS Pseudo-elements による「対話型規格ガイド」

顔の位置を目測だけでそろえるのは難しいため、画面に補助線を表示します。本ツールでは、クロップUIの内部にCSSの擬似要素を用いて、実装で位置を定めた「頭頂部」と「あご」のラインを動的に重畳させています。

なぜこの実装にしたのか

Canvasにガイドラインを描画する手法に比べ、DOM要素としてガイドを定義することで、切り抜き枠内の決まった割合の位置に線を重ねられます。また、pointer-events: none を指定することで、UIの操作性を損なうことなく、視覚的な補助のみを提供できるのがメリットです。

4枚をシート中央へ配置する開始位置の計算例です。寸法はすべて px です。

function mynumberSheet() {
  const width = 1051, height = 1500;
  const photoWidth = 413, photoHeight = 531;
  return { x: (width - photoWidth * 2 - 60) / 2,
    y: (height - photoHeight * 2 - 80) / 2 };
}

2. L判印刷用タイリングと座標計算アルゴリズム

「印刷用(L判)」モードでは、1枚のL判写真用紙(89mm × 127mm)に、35mm × 45mm 相当の写真を4枚配置します。ここでは、コンビニプリント等の写真間の隙間と中央位置の計算を行っています。

なぜこの実装にしたのか

印刷用は通常の画像データとして保存します。印刷方法や料金は利用するサービスで確認してください。Canvas上でミリメートル単位をDPI換算してピクセル座標に落とし込むことで、L判全体を 89×127mm で印刷した場合の寸法を基準に、シートを生成します。印刷機の自動拡大や余白設定までは制御しません。

3. クライアントサイドでのHEIC変換とメモリ最適化

このツールでは、HEICを選んだ場合はブラウザ内で別の画像形式に変換してから編集します。本ツールでは、heic2any を用いた動的変換と、後続の処理画素数を抑えるリサイズ処理をフロントエンドのみで完結させています。

なぜこの実装にしたのか

選んだ証明写真の変換と編集は、ブラウザ内で行います。HEIC変換から編集用の一時リサイズまでをすべてブラウザ上(Blob URL)で行うことで、「利便性」と端末内での画像処理を両立させています。

出力の仕様と確認する点

入力は長辺 3000px 以下に縮小します。Web 用は 700×900px に切り抜いた写真1枚の JPEG(品質指定 0.85)、印刷用は 1051×1500px のシートに 413×531px を2列×2行で配置した JPEG(品質指定 0.95)です。

頭頂部の目安は上から 8%、あごは 85% の線です。顔を自動検出して合わせる処理ではなく、線の間に収まったことだけで申請写真の適否を判断できません。線は保存画像に描き込みません。

Web 申請と郵送では使う出力を選び分けます。背景・表情・鮮明さ・撮影時期などは提出先の最新案内で確認し、印刷用は用紙への拡大率を確認してから切り取ってください。受理を保証するツールではありません。