Algorithm & UI/UX
ブラウザ完結型画像処理と、印刷用Canvasグリッドレンダリング
「履歴書写真メーカー」では、プライバシー保護のために全処理をクライアントサイドで完結させています。スマートフォン特有のメモリ制限を回避しつつ、高精度な印刷用データを生成するための実装を紹介します。
1. スマホのメモリ限界を回避する「動的スケーリング」
最近のスマートフォンの写真は非常に高解像度ですが、そのままCanvasで扱うと、モバイルブラウザのメモリ上限を超えてクラッシュする原因になります。本ツールでは、読み込み時にアスペクト比を維持したまま、安全な最大解像度まで一度ダウンスケールする前処理を挟んでいます。
これにより、低スペックな端末でも安定してエディタを動作させつつ、履歴書(40mm×30mm)として十分な鮮明さを維持した処理を可能にしています。
// 巨大な画像を読み込んだ際のクラッシュを防止するリサイズ処理
const MAX_DIMENSION = // 独自の最大解像度しきい値;
if (width > MAX_DIMENSION || height > MAX_DIMENSION) {
// 比率を計算してリサイズ後のサイズを算出
// ここにアスペクト比を維持した計算処理が入ります
const canvas = document.createElement('canvas');
canvas.width = targetWidth;
canvas.height = targetHeight;
const ctx = canvas.getContext('2d');
// 軽量化された画像を生成して以降の処理に渡す
ctx?.drawImage(img, 0, 0, targetWidth, targetHeight);
}
2. 2×3配置を実現するCanvasグリッドレンダリング
「印刷用(L判)」モードでは、1枚のL判用紙にちょうど6枚の写真が並ぶように配置する必要があります。ここでは、Canvasのマトリックス座標計算を用いて、余白(Gap)と各写真の位置を動的に算出しています。
単に並べるだけでなく、中央寄せ(Center Align)のオフセット計算を行うことで、どのようなプリンタでも写真が切れにくいレイアウトを保証しています。
// L判サイズに6枚(2x3)を最適に配置するループ処理
const startX = (canvas.width - (photoWidth * 2 + horizontalGap)) / 2;
const startY = (canvas.height - (photoHeight * 3 + verticalGap * 2)) / 2;
for (let row = 0; row < 3; row++) {
for (let col = 0; col < 2; col++) {
const x = startX + col * (photoWidth + horizontalGap);
const y = startY + row * (photoHeight + verticalGap);
// クロップ済みのパーツを各セルに描画
ctx.drawImage(originalCroppedCanvas, x, y, photoWidth, photoHeight);
// 切り取りガイド用の極細ストロークを付与
ctx.strokeStyle = '#e2e8f0';
ctx.lineWidth = // 独自のチューニング値;
ctx.strokeRect(x, y, photoWidth, photoHeight);
}
}
3. CSSによる「規格準拠UX」の実現
証明写真には「頭頂部からあごまでの比率」という厳格な規格がありますが、これを手動で合わせるのは非常に困難です。本ツールでは、Cropper.jsの内部要素にCSSの擬似要素(::before/::after)を注入し、視覚的な「ガイド線」をオーバーレイさせています。
複雑な数学計算をユーザーに強いるのではなく、「線に合わせる」という直感的な操作だけで規格準拠のデータを作成できる、フロントエンドならではの工夫です。
/* エディタ上に「頭頂部」と「あご」のガイド線を動的に表示 */
.cropper-view-box::before {
content: '--- 頭頂部 ---';
top: // 独自の配置比率;
/* その他、絶対座標とデザインの定義 */
}
.cropper-view-box::after {
content: '--- あご ---';
top: // 独自の配置比率;
/* その他、絶対座標とデザインの定義 */
}
Developer's Note
履歴書写真は、就職活動における大切な第一印象を決めるものです。しかし、写真機で撮ると800円〜1,000円ほどかかってしまいますし、撮り直しも回数に限りがあります。
そこで、「納得いくまでスマホで撮り直した一枚」を、いかにプロ級のバランスでデータ化できるかにこだわりました。赤色のガイド線は、一般的な履歴書写真の「好印象に見える顔の大きさ」を計算して配置しています。
「サーバーに送信しない」という安全性が、今の時代における真のユーザービリティだと信じて実装しました。