C ++でJPEG画像を8 x 8ブロックに分割する方法を教えてください。
ありがとう。
ああ、頑固なアプローチ。私の心はあなたに行きます。多くのことを学ぶことが期待されますが、そうすることで時間、血、痛みを失うことに注意してください.
圧縮 FAQには、JPEG の仕組みに関する詳細が記載されています。良い出発点は、パート 2: サブジェクト 75: JPEG の紹介です。
簡単に言えば、一般的な JPEG ファイルの場合、エンコード手順 6 から 4 を逆にする必要があります。
その後、適切な逆 DCT にフィードできる 8x8 ブロックが残るはずです。
ウィキペディアには、JFIF形式、ハフマン テーブル、およびJFIF 内の JPEGデータの構造に関する詳細が記載されています。
JPEG について学ぶために JPEG で遊んでみようと思っているのではないでしょうか? 実用的なアプリケーションがある場合、生のエンコードされたブロックへのアクセスはほぼ確実に必要ないためです。
コメントを見た後の編集: ファイル全体を読み取ったり解凍したりせずに、非常に大きな JPEG の一部だけを取得したい場合は、ImageMagick のstream
コマンドを使用できます。ファイル全体を読み取らずにサブイメージを取得できます。like egstream -extract 8x8+16+16 large.jpeg block.rgb
を使用して、(16,16) から始まる 8x8 ブロックを取得します。
画像を解凍し、turbojpg ライブラリ (非常に高速) を使用する必要があります。これによりunsigned char
、RGB (または RGBA) の配列が得られます。これで、RG と B にそれぞれバイト値を持つ圧縮されていないイメージができました。
char
ここから、3*8ブロックを通過する単純な for ループを作成し、それらをコピーして、memcpy
他のメモリ ロケーションに使用できます。
Turbojpg ライブラリから返される配列は、バイトの1 次元線形配列であることを覚えておく必要があります。したがって、スキャンラインは次々に保存されます。ブロックを作成するときは、これを考慮してください。必要に応じて、配列を別の方法でトラバースする必要があります。