5

または、代わりに、圧縮を処理するために使用するより良いライブラリがありますか?

この前に、私がすでに理解していることを説明します。(1)JPEGは不可逆であり、入力ファイルと同じようには見えません。(2)以下のコードで行ったように、圧縮品質設定を0.0から1.0の間で調整できます。

BufferedImageを取得してJPEGに変換し、JavaのImageWriterの.write()メソッドがJPEG画像の標準以下の結果を生成することに気づいています(例として、Photoshopの「Web用に保存」と比較して)。

私のコードは今少しこのように見えます:

// img is a BufferedImage, here
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(.75f);

IIOImage image = new IIOImage(img, null, null);
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
writer.setOutput(ImageIO.createImageOutputStream(byteArrayOut));
writer.write(null, image, iwp);
writer.dispose();

圧縮品質設定を試してみると、さまざまな品質の出力が生成されますが、「1.0」に設定しても、JPEGを作成するときに他のツールで得られるものほど見栄えがよくありません。

私は新しいユーザーで、まだ画像を投稿できないので...違いをデモするウェブページがあります。うまくいけば、同様の質問があるかもしれない将来のユーザーのために、いつかここに永久にそれらを入れることができます。

明らかに、この特定の画像はJPEG圧縮の最適な候補ではありませんが(PNGははるかに小さく、ロスレスです)、圧縮アーティファクトをより簡単に確認できます。実際の画像は、ほとんどが写真です。少なくとも、これは、JavaのJPEG圧縮のアルゴリズムと品質に疑問を投げかけるものであり、より少ないバイト数で元の画像に近い画像を生成する他の画像とは異なります。

4

1 に答える 1

5

「JavaのImageWriterの.write()メソッドは、JPEG画像の標準以下の結果を生成します(例として、Photoshopの「Web用に保存」と比較して)。」

これが発生する理由は複数あり、Javaimageioによって生成された画質をフォトショップとしてのプロの画像ソフトウェアと比較することは不公平です。

とにかく、画像のアーティファクトの最も可能性の高い原因を見てみましょう。通常、ソフトウェアが画像をJPEGとして保存する場合、ユーザーはパラメータを圧縮または品質のいずれかとして指定できます。一方は他方の逆です。このパラメータは、JPEG損失の最も重要な要因である量子化プロセスで使用される量子化テーブルをスケーリングするために使用されます。エンコーダが異なれば、画質の違いを部分的に説明する異なる量子化テーブルを使用する場合があります。

しかし、圧縮と画質に影響を与える他の要因が存在する可能性があります。その中には、量子化プロセスの前に実際に行われるクロマサブサンプリング(またはダウンサンプリング)があります。クロマサブサンプリングは、画像の色情報を元の画像よりも低い解像度でサンプリングするプロセスです。より良い説明については、この記事を読んでください。

Calvin Hassは、 http://www.impulseadventure.comからダウンロードできるJPEGSnoopと呼ばれる優れたJPEGダンピングツールを提供します。提供したps75.jpg画像でこのツールを使用すると、クロマサブサンプリングに関連する次の出力が見つかりました。

 Component[1]: ID=0x01, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y)
 Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cb)
 Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 1 x 1), Quant Tbl Sel=0x01 (Chrom: Cr)

これは、カラーコンポーネントに対してサブサンプリングが行われないことを意味します。一方、100.jpgと75.jpgの両方のサブサンプリング部分は同じです。

 Component[1]: ID=0x01, Samp Fac=0x22 (Subsamp 1 x 1), Quant Tbl Sel=0x00 (Lum: Y)
 Component[2]: ID=0x02, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cb)
 Component[3]: ID=0x03, Samp Fac=0x11 (Subsamp 2 x 2), Quant Tbl Sel=0x01 (Chrom: Cr)

これは、2つの連続するピクセルの平均をとることにより、色成分の水平方向と垂直方向の両方でサブサンプリングが行われたことを意味します。

クロマサブサンプリングが画質に与える影響は、元の画像があなたの場合のようにストリップや正方形で構成されていて、アーティファクトがここで見やすいことにすでに気付いている場合に最も顕著になります。

したがって、IMOの場合、この特殊なケースでは、問題は品質係数の設定よりもクロマサブサンプリングにあります。十分に掘り下げていないかもしれませんが、imageioまたはその背後にあるImageWriter(おそらくcom.sun.imageio.plugins.jpeg.JPEGImageWriter)のサンプリング係数を設定する方法を見つけることができませんでしたが、設定することは可能です。 ImageWriterで使用される量子化テーブルとハフマンテーブル。

したがって、imageio用またはスタンドアロンプ​​ラグインとして独自のImageWriterプラグインを作成しない限り、JavaのImageWriterで使用される圧縮アルゴリズムを変更できる可能性はほとんどありません。しかし、JEPG圧縮アルゴリズムの複雑さを考えると、どちらも重要です。James R.Weeksによって作成されたJavaJpegEncoderの実装を比較的簡単に追跡できるものがあります。これは、デフォルトではクロマサブサンプリングを行いません。以前は無料でしたが、Webを検索すると元のバージョンを見つけることができます。

もう1つの興味深い点は、JPEGSnoopの出力から、photoshopによって保存された75%JPEG画像の実際の品質係数は実際には約92%と示されていることです。そして、Calvin Hassのウェブサイトから引用された次のテキストは、あなたのケースでフォトショップがサブサンプリングを使用しない理由の質問に答えます。

余談ですが、Photoshop CS2は、[JPEG品質の保存]設定に応じて異なるクロマサブサンプリングレベルを使用することに注意してください。

Photoshop Save As Quality 0-6 - 2x2 Chroma Subsampling
Photoshop Save As Quality 7-12 - 1x1 No Chroma Subsampling
Photoshop Save For Web Quality 0-50 - 2x2 Chroma Subsampling
Photoshop Save For Web Quality 51-100 - 1x1 No Chroma Subsampling

JPEG画像も書き込めるこのJava画像ライブラリをチェックしてください。

于 2012-06-10T19:37:53.473 に答える