猫の手ツール

Algorithm & UI/UX

バーチャルメイクの裏側:肌質を殺さない「多層ブレンディング」とAIパーツ認識

「デジタルな塗りつぶし」を「自然な血色」へ。本ツールではAIによる数百点の座標解析と、Canvas APIの高度な合成処理を組み合わせることで、毛穴や肌の質感を残したままメイクを施すロジックを実装しています。

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

現行コードの確認日:

入力
人物写真を選び、リップとチークの色・濃さをそれぞれ調整します。
処理
唇の輪郭と頬の位置をFaceLandmarkerから取り、唇の色合成と頬のグラデーションを別の描画で重ねます。
出力
最大5人の顔を検出し、入力は長辺1500px以下へ縮小、JPEG品質0.9で保存します。

まず確認する点:リップとチークは異なる範囲へ作用します。片方ずつ確認してから合わせると、横顔や髪に色が掛かるずれを見つけやすくなります。

仕上がりの例

人物の顔に、リップとチークの色を加えた例です。

加工前・加工後
左は人物の顔写真。右は唇を赤くし、頬に淡い色を加えた顔写真。

サンプルにはAIで生成した架空の人物画像を使用しています。

加工前・加工後

左は人物の顔写真。右は唇を赤くし、頬に淡い色を加えた顔写真。

掲載画像はサイトにある既存の公開作例です。保存済みの資料ではAIで作成した架空の人物・手の画像を使用しています。今回の確認日が、この作例を実行した日を表すわけではありません。

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

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

記録の入力画像
1788×2400px (JPEG)
記録の出力画像
1117×1500px (JPEG)
保存済み記録の主な操作・出力条件
画面の項目記録の値現行コードの初期値・範囲
色#ff4d6d初期値 #ff4d6d
リップ強度40初期値 40 / 範囲 0〜100
チーク強度 (自然)30初期値 30 / 範囲 0〜100
チークの範囲60初期値 60 / 範囲 20〜150

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

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

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

仕組みを読み進めるときは、MediaPipeの顔ランドマーク(顔の点を使う描画と変形)、Canvas APIと画像処理(画像寸法、drawImage、画素と透明度の扱い)が参考になります。

1. 肌に馴染ませる「Soft-Light & Overlay」合成アルゴリズム

単にCanvasで色を塗るだけでは、肌のテクスチャが塗りつぶされ、不自然な「貼り付け感」が出てしまいます。本ツールでは、チークの描画において soft-light(ソフトライト)と overlay(オーバーレイ)を組み合わせる多層的なブレンディングを採用しています。

まず、放射状グラデーションを用いて中心から外側へ馴染む色面を作成し、soft-light モードで合成します。元の肌の明暗を利用して色を重ねます。ただし、元写真の暗さや選択色によっては暗く見える場合があります。さらに、極めて低い透明度で overlay を重ねることで、ハイライト成分を補完し、内側から上気したような立体感を生み出しています。

チークの中心が求まった後の合成例です。ctxは描画先、colorは選んだ色、opacityは0〜1、radiusは画像幅と範囲スライダーから計算した半径です。

function cheek(ctx, x, y, radius, color, opacity) {
  const gradient = ctx.createRadialGradient(x, y, 0, x, y, radius);
  gradient.addColorStop(0, color);
  gradient.addColorStop(1, 'rgba(0,0,0,0)');
  ctx.save();
  ctx.beginPath();
  ctx.arc(x, y, radius, 0, Math.PI * 2);
  ctx.fillStyle = gradient;
  ctx.globalCompositeOperation = 'soft-light';
  ctx.globalAlpha = opacity;
  ctx.fill();
  ctx.globalCompositeOperation = 'overlay';
  ctx.globalAlpha = opacity * 0.3;
  ctx.fill();
  ctx.restore();
}

2. 解像度に依存しない「動的スケーリング」座標マッピング

スマホで撮った高画質な写真と、Webカメラの低解像度な画像では、唇や頬の「適切なサイズ」は全く異なります。本ツールでは、AIが検出した顔全体の幅やキャンバスサイズに基づき、エフェクトの半径やぼかし量を動的に算出しています。

例えば、チークの範囲は固定ピクセルではなく、キャンバスの横幅に対する radiusFactor(係数)として定義されています。これにより、どんな解像度の写真がアップロードされても、画像全体の解像度に合わせて半径が変わります。顔幅から直接決めているわけではないので、顔が小さく写った写真では範囲を手動で小さくする必要があります。

3. WASMエンジンによる完全ローカル・プライバシー保護

自撮り写真は極めて機密性の高い個人情報です。本ツールでは MediaPipe の Face Landmarker モデルを WebAssembly (WASM) 経由でブラウザ内で直接実行しています。画像データをサーバーに1バイトも送信することなく、クライアントのGPU/CPUリソースのみで 5人分までの顔を検出できる設定で、読み込んだ静止画へメイクを合成します。

出力の仕様と確認する点

リップの濃さ、チークの濃さ、チークの範囲を別々に調整します。チークの中心はランドマーク205・425で、半径は画像幅×範囲設定÷1000です。顔の向きや輪郭に合わせた手動の位置変更はありません。

リップは外周のパスを塗る方式で、口の内側を抜くマスクはありません。口を開いた写真では歯や口内へ色が重なる場合があります。唇だけを詳しく調整するリップ試着ツールとは処理が異なります。

最大5人の顔を検出し、入力は長辺1500px以下へ縮小、JPEG品質0.9で保存します。写真の色を変える効果であり、実際のメイク商品の色や質感との一致を保証するものではありません。

制作時に確かめたこと