猫の手ツール

Algorithm & UI/UX

情報の欠落を「美しさ」に変える、意図的な劣化アルゴリズム

現代の写真は、レンズの進化と画像処理エンジンの向上により、あまりに「正解」を映し出しすぎます。このツールでは、あえて解像度を破壊し、色の階調を間引くことで、かつての「ガラケー画質」特有の情緒を再現しています。

1. Canvasリサンプリングによる「ドット感」の強調

単にCSSで画像を小さく表示するだけでは、ブラウザの補間機能によって画像がぼやけてしまいます。あの頃の粗い質感を出すには、Canvas上で「補間を無効化」した状態でリサイズを行う必要があります。

具体的には、オフスクリーンCanvasを用いて一度低解像度のイメージを生成し、それを描画する際にimageSmoothingEnabled = falseを適用。これにより、ピクセルが引き伸ばされる際の滑らかなグラデーションを排除し、鋭利なドット感を維持しています。

// 意図的な低解像度化のプロセス
const ctx = offscreen.getContext('2d');
// ブラウザによる滑らかな補間を無効化し、ドットを際立たせる
ctx.imageSmoothingEnabled = false;

// 指定されたターゲット幅(例:240px)に縮小描画
ctx.drawImage(originalImage, 0, 0, targetWidth, targetHeight);

2. ビット深度のシミュレーション(減色アルゴリズム)

2000年代のディスプレイは表示できる色数が限られていました。最新のフルカラー(24bit)画像を、16bitや8bit相当のパレットへ強制的に落とし込む処理をJavaScriptで実装しています。

各ピクセルのRGB値に対して、独自のステップ数(しきい値)を用いたビット演算を行うことで、滑らかなグラデーションを「等高線」のような模様(マッハバンド)へと変化させます。これが「古いデジタル機器」特有のザラつきの正体です。

// 色の階調を間引くコアロジック(擬似コード)
for (let i = 0; i < data.length; i += 4) {
    // 独自の係数を用いて各チャネルの階調を制限
    const step = calculateStep(config.bitDepth); // 階調幅を算出
    
    // 情報を欠落させる計算処理
    data[i] = Math.floor(data[i] / step) * step;     // Red
    data[i+1] = Math.floor(data[i+1] / step) * step; // Green
    data[i+2] = Math.floor(data[i+2] / step) * step; // Blue
    
    // 微細なランダムノイズの付与
    const noise = (Math.random() - 0.5) * NOISE_FACTOR; // 独自のノイズ値
    // ...各色に加算処理
}

3. JPG圧縮ノイズの意図的な再現

最後の仕上げは、保存時の「圧縮ノイズ」です。当時の通信環境やストレージ容量の制限により、写真は高い圧縮率で保存されていました。

このツールでは、Canvasからデータを書き出す際、あえてクオリティ係数を低く設定することで、ブロックノイズやモスキートノイズを発生させています。これもまた、当時を感じさせる重要なスパイスとなります。

// 保存時の処理
// あえて低いクオリティ値を指定することで、JPG特有の圧縮ノイズを意図的に発生させる
const dataUrl = canvas.toDataURL('image/jpeg', 独自のチューニング値);

Developer's Note

このツールを開発する上で最もこだわったのは、単なる「汚い画像」にならないようにすることです。思い出の中のガラケー写真は、実は解像度こそ低いものの、脳内補完によって美化されています。

そのため、減色処理の際にはわずかなランダムノイズを加え、無機質なデジタル劣化に「アナログ的な揺らぎ」を持たせるように調整しました。また、HEIC形式などの最新フォーマットをブラウザ側でJPEGに変換する処理を挟むことで、現代のデバイスでもストレスなく「あの頃」へタイムスリップできる体験を目指しています。