猫の手ツール

Algorithm & UI/UX

ユークリッドの互除法と許容誤差を用いた「直感的なアスペクト比判定」の仕組み

本ツールでは、アップロードされた画像のピクセルサイズから、単なる除算結果だけでなく「4:3」や「16:9」といった人間が理解しやすい規格を導き出しています。その核となる計算処理と、ストレスのない入力UIを実現するための状態管理について解説します。

1. 最大公約数(GCD)による最小整数比の算出

画像サイズが「4000x3000」であっても、ユーザーが知りたいのは「4:3」という比率です。本実装では、ユークリッドの互除法を用いて横幅と高さの最大公約数を求め、それぞれの値をその公約数で割ることで、最小の整数比を算出しています。

ただし、デジタル写真ではごく稀に数ピクセルの誤差が含まれることがあります。そのため、あまりに大きな素数が含まれるようなケース(簡約化しても 127:128 になるような場合)は、あえて「1.23 : 1」のような小数表記に切り替える処理を加え、情報の有用性を担保しています。

// 最大公約数を求める再帰関数(ユークリッドの互除法)
function getGcd(a, b) {
    // ここに最大公約数の計算ロジックが入ります
}

// 算出されたGCDを用いて比率を簡約化
const gcdVal = getGcd(width, height);
const rw = width / gcdVal;
const rh = height / gcdVal;

// ユーザーに提示する比率表示の切り分け
const displayRatio = (rw > // 簡約化の閾値) 
    ? `${(width / height).toFixed(2)} : 1` 
    : `${rw} : ${rh}`;

2. 許容誤差(Tolerance)を用いた規格マッチングアルゴリズム

世の中の画像には、厳密には「16:9」ではないものの、実質的にその規格として扱いたい画像が多く存在します。例えば、1ピクセルの計算誤差やトリミングミスがある場合です。

本ツールでは、各有名比率に対して「許容誤差(Tolerance)」を定義しています。計算されたアスペクト比と規格値の差分がこの閾値以内であれば「16:9 です」と断定的に表示する仕組みを採用し、UXを向上させています。

// 有名比率の定義と判定ロジックの概念
const commonRatios = [
    { name: '16:9', val: 1.777..., tol: // 独自の判定閾値 },
    { name: '4:3',  val: 1.333..., tol: // 独自の判定閾値 },
    // ...
];

// 入力画像の比率と最も近い規格を探す
const matched = commonRatios.find(cr => {
    const diff = Math.abs(currentRatio - cr.val);
    return diff <= cr.tol;
});

3. 循環更新を防ぐ「isUpdating」フラグによる双方向バインディング

「横幅を変えたら高さも変わる、高さを変えたら横幅も変わる」というリサイズ計算機能では、イベントの無限ループ(循環更新)を防ぐ必要があります。

単純なイベントリスナーの連鎖を避けるため、更新中であることを示す内部フラグを設け、プログラムによる値の書き換え時には他方のリスナーが反応しないように制御しています。これにより、計算機のスムーズな操作感を実現しています。

let isUpdatingInput = false;

inputWidth.addEventListener('input', () => {
    if (isUpdatingInput) return;
    
    isUpdatingInput = true;
    // 比率に基づいた高さの自動計算
    inputHeight.value = // 計算処理...
    isUpdatingInput = false;
});

inputHeight.addEventListener('input', () => {
    if (isUpdatingInput) return;
    
    isUpdatingInput = true;
    // 比率に基づいた横幅の自動計算
    inputWidth.value = // 計算処理...
    isUpdatingInput = false;
});

Developer's Note

このツールを作る上で最も意識したのは、「計算結果の優しさ」です。単に数値を出すだけなら電卓で十分ですが、Web制作者やSNS運用者が求めているのは「これはYouTubeサイズ(16:9)として使えるのか?」という確信です。

技術的には heic2any を用いたクライアントサイドでのHEIC変換にも対応させ、iPhoneユーザーが撮影した写真をそのままアップロードしても動くように設計しました。すべてをブラウザ内で完結させることで、プライバシーを守りつつ、デスクトップアプリ並みの応答性を目指しています。