13

最初にデコードせずに、多くのjpegを無損失で結合するプログラム(Javaで問題あり)を作成しようとしています。

私はシンプルに始めて、同じ設定で圧縮された同じサイズの 2 つの jpeg を 16 進エディターを使用して上下に追加しようと考えました。

最初に jpeg B の画像データを抽出し、それを jpeg A に追加します。ヘッダーで指定された寸法を変更することにより、表示可能な新しい認識可能な画像 (jpeg A + y 軸に追加された jpeg B) を取得します。ただし、jpeg B からの画像データははっきりと認識できますが、多くの色情報が失われているようで、明らかに正しくありません。

だから私の質問は、私がここで見逃しているステップは何ですか? 変更する必要があるディメンション固有のヘッダー値は他にないと思うので、両方の jpeg から画像データをハフマン デコードし、それらを一緒に追加してから、ロットを再エンコードする必要があるのではないでしょうか?

私は jpeg の仕様やヘッダーなどを読むのに時間を費やしましたが、正直に言うと、私は深みがなく、1 つか 2 つのポインターで本当にできることです!

助けてくれてありがとう。


すべての提案をありがとう。はい、これは間違いなく可能です。元の質問で jpegtran について言及する必要がありました。私は基本的に jpegtran 機能のこの側面を複製しようとしていますが、それを自分のプログラムで使用しています。jpegtran のソースを見るべきだと思いますが、C については何も知らないし、一般的なプログラミングについてもあまり知らないので、ソース コードのリバース エンジニアリングは言うは易く行うは難しです!

4

8 に答える 8

20

これは非常に実行可能です。たくさんの Google マップの画像タイルを結合してポスター サイズの画像を作成しました。まさにこれを行うための JPEG Tools と呼ばれる Unix 用のパッケージがあります。このプログラムはjpegjoinと呼ばれます。Pure C ソース、Windows バイナリが利用可能。コンパイルするとコマンド ライン アプリケーションが作成されます。このアプリケーションを実行すると、2 つの jpeg 画像がロスレスに結合されます。画像を解凍するのではなく、圧縮されたデータをマージして、それに応じてヘッダーを修正するだけです。これを使用して 100 枚の画像を結合して 50 個のストリップを作成し、それらのストリップを再度結合して大きな画像を作成しました。

詳細については、http://en.wikipedia.org/wiki/Lossy_compression#Lossless_editingをご覧ください。

ソースコード

基礎となるjpegtranライブラリのソース コードは、ここにあります。jpegjoinを模倣するサンプル スクリプトはこちらです。

于 2009-03-04T08:42:02.540 に答える
3

わかりました、どこが間違っていたのかわかりました。

1) 画像スキャン データはバイト単位で保存されますが、実際の重要な情報は可変長のビット文字列としてエンコードされます。これは、実際のイメージ データの末尾が必ずしもバイト境界にあるとは限らないことを意味します。JPEG エンコーダーがバイト境界を作成するためにビット数をパディングする必要がある場合、単純に一連の 1 を追加します。

2) 実際のピクセル情報が保存される方法は、(少なくとも私にとっては) 説明するには少し複雑すぎますが、基本的にすべてが MCU 内、最小コーディング ユニットなどでエンコードされます。これらのサイズはクロマ サブサンプリングによって異なり、水平および垂直サイズは 8 または 16 ピクセルです。各 MCU には、輝度 (Y) またはクロミナンス (Cb と Cr) の単一コンポーネントを構成する DC 部分と AC 部分があります。問題は、DC コンポーネントが以前の MCU の関連する DC 値に関連する値として保存されることでした。そのため、jpg B から新しい画像データを追加したとき、DC 値は 0 を基準にして保存されていましたが (以前の MCU がなかったため)、jpg A からの最後の MCU の最終的な DC 値を考慮する必要がありました。 (それが理にかなっていることを願っています)。

ソリューション:

画像データの最初のデコード (ハフマン + ランレングス) を実行して、画像データがどこで終了するかを正確に見つけてから、末尾の 1 を削除する必要があります。また、2 番目の jpg の初期 DC 値を適切に変更する必要があります。次に、適切なビットを再エンコードし、バイト境界に合わせて 1 を追加する必要があります。

x 軸に追加する場合は、もう少し複雑です。MCU が正しい順序でスキャンされるように、MCU を再配置する必要があります。jpgs は左から右、次に上から下にスキャンし、DC 値を適切に調整します。

これまでのところ、単一の MCU jpg でのみこれをテストしましたが、理論的には、より大きなものでも動作するはずです。

ところで、この優れたjpg関連のリソース/ブログの所有者のおかげで、私はこれを解決しました

于 2009-03-19T16:13:41.703 に答える
2

jpeg は - mp3 のように - 通常、再圧縮すると安定します (同じアルゴリズムを使用)。

そのため、画像を結合して再圧縮するときは、新しい圧縮率が 2 つの画像の最高値以上であることを確認してください。そうすれば、正確さを失うことはありません。

于 2009-03-04T08:23:19.793 に答える
2

2 つのアプローチ:

1) 両方のソース JPEG イメージをデコードし、結果のビットマップをマージして、JPEG として再度エンコードします。ここでの欠点は、再圧縮です。

2) ソース イメージの幅と高さが 16 の倍数であることを確認します。画像をデコードせず、代わりにソース MCU ブロックからターゲット JPEG を組み立てます (16 x 16 ピクセル サイズ、したがってクロッピング)。

于 2009-03-04T08:29:06.223 に答える
1

DRIマーカーとRSTnマーカーを検討することをお勧めしますが、これには多くの前提条件が必要ですが、私にとってはうまくいきます。DRIとRSTnを使用してエンコードされたjpegにPPM(ビットマップ形式)を追加します。どちらも同じ幅です。両方ともMCUの倍数です。

最後のRSTnマーカー(存在する場合)の後のjpegデータを切り取り、これをPPMにデコードし、2つのPPMを1つのMCUラインに結合し、元のjpegと同じオプションでエンコードし、結果のRSTを再配置します。元のjpegに従ってjpegを作成し、その結果を元のjpegに追加します。この方法を使用すると、元のjpeg全体をデコードして再度エンコードすることができなくなります。

デコードとエンコードとして、libjpegを使用しています。

于 2012-07-20T02:20:41.867 に答える
0

画像を水平方向に追加する代わりに、各画像を 90 度回転させてから垂直方向に結合し、結果の画像を -90 度回転させた方がおそらく簡単です。

于 2013-05-02T12:58:04.477 に答える
-3

ロスレス JPEG 操作は矛盾した表現です。回転などのトリックを行うこともできますが、それだけです。

ロスレスのソース画像 (TIFF または PNG が思い浮かびます) を用意するか、画質の要件を再評価することをお勧めします。適切な元のファイルが与えられた場合、JPEG をもう一度再サンプリングすることは、そこにいる大多数の人々にとって区別がつきません。

于 2009-03-04T07:52:19.307 に答える
-4

あなたがしようとしていることは、基本的に不可能です。
JPEG ファイルのエンコーディングはやや複雑で、ピクセルの内容を変更すると、エンコーディングも変更されます。結合した 2 つの画像の合計よりも小さいまたは大きい画像になる可能性があります。無損失で可能な操作は、元の画像のピクセルと 1 対 1 の対応を維持する操作のみです。これは基本的に 90 度回転に要約されます。

于 2009-03-04T08:24:31.693 に答える