世界を動かす技術を、日本語で。

後退的JPEG

2026年7月18日原文(maurycyz.com)

概要

  • JPEGファイル は低周波成分を先に保存する機能を持つ
  • 部分的にダウンロードされた画像でも 低解像度プレビュー が表示可能
  • 複数のスキャンで画像データを段階的に復元
  • スキャン構造を利用した アニメーション的表現 も可能
  • 実用性は低いが、技術的な遊びや実験には最適

JPEGのプログレッシブスキャン機能の仕組み

  • JPEGファイル は「スキャン」と呼ばれる複数のデータブロックで圧縮データを保存
  • 各スキャンは ヘッダー で始まり、異なる周波数成分を段階的に格納
  • 例:最初のスキャンは DC成分 (最低周波数)を3つのカラーチャンネル(Y, Cb, Cr)分含む
    • Y :輝度(明るさ、画質に最重要)
    • Cb, Cr :クロマ(色、精度を落としても見た目に影響しにくい)
  • JPEGの色空間は YCbCr。RGBとは異なり、色と明るさを分離
    • おおまかな変換式:Y = G, Cb = B - G, Cr = R - G
  • スキャンごとに DCT係数の範囲精度 を指定
    • 低解像度プレビュー → 詳細追加 → フルクオリティへと変化

スキャン構成例

  • 1スキャン目: DC成分 のみ(超低解像度プレビュー)
  • 2スキャン目以降: AC成分 や精度を増やして詳細を追加
  • 最後のスキャンで フルクオリティ画像 完成
  • カラーデータは 半分の解像度 で保存されるため、輝度データよりも容量が小さい

JPEGのスキャンを利用した画像切り替え・アニメーション

  • 同じ解像度の複数画像を スキャン単位で連結 し、部分的にデータを上書き
    • ヘッダーやフッター(SOI, SOF, EOI)を除去して連結
    • 通常のJPEGデコーダは一定数のスキャン後に処理を打ち切る(セキュリティ対策)
  • 90フレーム程度 ならChromeなど主要ブラウザで表示可能
    • Firefoxはさらに多くのスキャンに対応
  • 各スキャンが DC成分のみ の場合、1/16解像度の画像が作成される
  • AC成分を含めると「ゴースト」現象(前フレームの残像)が発生するため、DCのみに限定

実験的利用と応用例

  • jpegtran などのツールでDCスキャンのみのファイルを簡単に生成可能
  • これを応用し、 1枚のJPEG画像に複数フレームの動画 をパックすることも可能
    • ネットワーク遅延やデコーダの仕様に依存し、再生タイミングの制御は不可
  • HTMLの <dialog>タグ や、CSS/JavaScriptなしのインタラクティブSPAでも応用例あり

制限と注意点

  • 実用的なアニメーションフォーマットとしては 不向き
    • 再生タイミング制御不可
    • スキャン数に上限あり
  • 主に 技術的な遊びトリック画像、デモ用途向け
  • 関連Cコード(merge.c)なども公開されている

関連リンクやツール

  • jpegtran :スキャン構造を編集できるコマンドラインツール
  • badapple.rose.systems :HTMLのみで動作するデモページ
  • /projects/bad_jpeg/merge.c :スキャン連結用のCプログラム

この技術を使えば、JPEGの仕様を超えた ユニークな画像表現遊び心ある仕掛け が作成可能。標準的な画像用途には向かないが、知識として覚えておくと面白い。

Hackerたちの意見

いいね!ウェブサーバーが「jpeg」をその場で生成して、クライアントにタイミングを合わせて送信することで、ある程度タイミングを調整できると思うよ。ソースはウェブカメラでもいいから、「jpeg」は永遠に続くかもね。

すでにこれをやっているウェブカメラもあるけど、彼らは'multipart/x-mixed-replace'のmimeトリックを使ってるんだ。要するに、サーバーがクライアントに「今送ったデータを、これに置き換えて」って言ってるようなもんだよ。JavaScriptは必要ないし、普通のHTTPとJPEGで動く。

たくさんのIPカメラがこれを実現してるよ。詳細はここで見てみてね:https://en.wikipedia.org/wiki/Motion_JPEG

最初の画像の「間違った」係数から高周波係数を計算する難しい方法を考えようとしたんだけど…これは賢いね。単純に一緒にぶつけちゃえばいいんだ。ある画像の低周波と別の画像の高周波を組み合わせる。意外と上手くいくね!

すごいハックだ!アニメーションGIFをJPEGに変換するのは絶対に可能だと思う。フレームを繰り返すことで、アニメーションを少し遅くすることもできるだろうね。

サーバーが正しい再生時間に合わせてデータを送信するようにすることもできるよ。サーバーがPythonやNode.js、PHP、その他何でも使っているなら、各フレームにdelay()を追加するのは簡単だし。

それは1. 呪われてる、そして2. 確実にここにいるべきものだね。

これが俺がここに来る理由だよ。

オンラインポルノ業界がこれを使ってないなら、たぶん価値がないね。でも、面白いけど。

再生は完全にネットワークの遅延に依存してるよ。サービスワーカーを使えば、遅い接続をエミュレートできるよ :)

JPEG-XLでこれができるか気になるな。実際にアニメーションサポートがあるのは知ってるけど、これはまた別の話だね。

このフォーマットはプログレッシブデコーディングをサポートしてるけど、確か現行のブラウザ実装ではサポートされてないはず。最初のChromeとFirefoxの実装は対応してたし、新しいRust実装のロードマップにも載ってると思う。WebKit/Safariについては全然わからない。追記:このフォーマットは関心領域デコーディングもサポートしてて、両方の機能を使えば面白いマップやフラクタル画像が作れると思う。でも、今はその実装を優先してないみたい。

Hacker Newsで議論の続きを見る