猫の手ツール

Algorithm & UI/UX

AI微笑み補正:バイリニア補間リキッド処理による自然な表情変形

「笑顔を後から作る」ためには、単に画像を歪ませるだけでは不十分です。本ツールでは、AIが解析した顔の筋肉構造に基づき、独自のピクセル操作エンジンで滑らかな変形を実現しました。その実装のこだわりを技術的視点で紐解きます。

1. iOS Safariの制限を越える「自前Liquifyエンジン」

画像の特定部分を歪ませる「リキッド処理」は、ブラウザ標準のCSSフィルタでは実現できません。また、一部のブラウザでは高度なCanvas操作がフリーズの原因になることもあります。

本ツールでは、getImageData で取得したピクセル配列を、バイリニア補間(双線形補間)を用いて直接計算・再配置する独自のワープ関数を実装しました。これにより、変形後のエッジがギザギザにならず、まるでフォトショップの「ゆがみツール」のような滑らかな質感をブラウザ上で再現しています。

// ピクセルワープ処理の核心部分
function applyLiquify(ctx, cx, cy, radius, dx, dy) {
    // 1. 指定範囲のピクセルデータを取得
    const imgData = ctx.getImageData(x, y, w, h);
    const srcData = new Uint8ClampedArray(imgData.data);
    
    for (let iy = 0; iy < h; iy++) {
        for (let ix = 0; ix < w; ix++) {
            // ここで中心からの距離に基づき「引っ張り量」を計算
            const effect = // 中心ほど強く、縁で0になる独自の減衰関数
            
            // サンプリング元の座標を逆方向に計算(ピクセルを引っ張る)
            let sx = ix - dx * effect;
            let sy = iy - dy * effect;
            
            // 2. バイリニア補間で周囲4ピクセルから色を決定
            // ここに〇〇(補間計算)の処理が入ります
            
            imgData.data[destIdx] = interpolatedValue;
        }
    }
    // 3. 計算したデータをCanvasへ戻す
    ctx.putImageData(imgData, x, y);
}

2. 顔のスケールに追従する「動的エフェクト範囲」の計算

アップロードされる写真の解像度や、顔の大きさは千差万別です。「口角を50px上げる」といった固定値での処理は、顔が小さい場合に崩壊を招きます。

本ツールでは、AIが検出した左右の口角の距離(口幅)を基準単位(Unit)として採用しています。変形させる半径や移動ベクトルをこの距離に対する割合で計算することで、どんなサイズの写真であっても常に「解剖学的に正しい位置」に笑顔の補正を適用できる設計にしています。

// 顔のサイズに基づいた動的なパラメータ設計
const mouthDist = // AI座標から左右の口角の距離を算出
const mouthRadius = mouthDist * // 独自のチューニング値(半径)
const eyeRadius = mouthDist * // 独自のチューニング値(半径)

// 移動ベクトルも口の大きさに比例させる
if (mouthIntensity > 0) {
    const dy = -(mouthDist * // 独自の係数) * mouthIntensity; // 上方向へ
    const dx = (mouthDist * // 独自の係数) * mouthIntensity;  // 外側へ
    
    // 自前エンジンで適用
    applyLiquify(ctx, x, y, mouthRadius, dx, dy);
}

3. `willReadFrequently` による描画パフォーマンス最適化

本ツールはスライダーを動かすたびに、高解像度画像のピクセルデータを読み取り・計算・描画しています。これは本来、ブラウザにとって非常に重い処理です。

そこで、Canvasコンテキストの取得時に willReadFrequently: true オプションを明示的に指定しています。これにより、ブラウザのバックエンドでソフトウェア描画の最適化が働き、ピクセルデータの読み取りにかかるオーバーヘッドを大幅に削減。モバイル端末でもヌルヌルと表情が変わる快適な操作感を実現しました。

Developer's Note

「無表情な写真を笑顔にする」というタスクにおいて、最も難しいのは「不自然さの排除」です。口角だけを上げるといわゆる「ジョーカー的な笑顔」になってしまうため、本ツールでは目元のやさしさ(頬のリフトアップ)も同時に調整できるようにしました。

技術的には、すべての計算を requestAnimationFrame 内で完結させ、UIスレッドをブロックしないように工夫しています。また、HEIC形式の自動変換など、スマホユーザーがストレスなく「最高の自分」を作れるような配慮を随所に散りばめました。