20

Java2D を使用して、Web サイトにアップロードされた写真のサイズを変更していますが、問題が発生しました (一見古い問題、参照: http://forums.sun.com/thread.jspa?threadID=5425569 ) - いくつかの特定の JPEGバイナリデータを含む InputStreamCMMExceptionを試みると、 aが発生します。ImageIO.read()

java.awt.color.CMMException: Invalid image format
 at sun.awt.color.CMM.checkStatus(CMM.java:131)
 at sun.awt.color.ICC_Transform.<init>(ICC_Transform.java:89)
 at java.awt.image.ColorConvertOp.filter(ColorConvertOp.java:516)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.acceptPixels(JPEGImageReader.java:1114)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1082)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:897)
 at javax.imageio.ImageIO.read(ImageIO.java:1422)
 at javax.imageio.ImageIO.read(ImageIO.java:1326)
    ...

ImageIO.read()(呼び出し、サーブレット コードなどであるスタック トレースの残りの部分を切り取りました)

特定のカメラで撮影した写真に絞り込み、このエラーをトリガーする写真を選択しました: http://img214.imageshack.us/img214/5121/estacaosp.jpg . これは Sun の JVM でのみ発生することに気付きました (Linux および Mac では、1.6.0_20 でテストしたところです)。OpenJDK を使用したテスト マシンは、おそらく JPEG リーダーの実装が異なるため、問題なく同じ写真を読み取ります。

残念ながら、本番環境で JVM を切り替えることも、ImageMagick ( http://www.imagemagick.org/ )などのネイティブに依存するソリューションを使用することもできません。

それを考慮して、私の質問は次のとおりです。リンクされたような写真を処理できる ImageIOs JPEG リーダーの代替品は存在しますか? そうでない場合、使用できる 100% 純粋な Java の写真のサイズ変更ソリューションは他にありますか?

ありがとうございました!

4

3 に答える 3

12

おそらく役立つライブラリの 1 つは、Java Advanced Imaging Library ( JAI )です。

このライブラリを使用すると、ImageIO を使用するよりもかなり複雑になる可能性がありますが、実行したばかりの簡単なテストでは、リンクした問題の画像ファイルを開いて表示しました。

public static void main(String[] args) {
        RenderedImage image = JAI.create("fileload", "estacaosp.jpg");

        float scale=(float) 0.5;

        ParameterBlock pb = new ParameterBlock();
        pb.addSource(image);

        pb.add(scale);
        pb.add(scale);
        pb.add(1.0F);
        pb.add(1.0F);

        pb.add(new InterpolationNearest() );// ;InterpolationBilinear());
        image = JAI.create("scale", pb);

        // Create an instance of DisplayJAI.
        DisplayJAI srcdj = new DisplayJAI(image);

        JScrollPane srcScrollPaneImage = new JScrollPane(srcdj);

// Use a label to display the image
        JFrame frame = new JFrame();

        frame.getContentPane().add(srcScrollPaneImage, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }

このコードを実行すると、画像が正常に読み込まれるようになります。次に、ParamaterBlock を使用して 50% サイズ変更されます

最後に、ファイルを保存したい場合は、次のように呼び出します。

String filename2 = new String ("tofile.jpg");
  String format = new String ("JPEG");
  RenderedOp op = JAI.create ("filestore", image, filename2, format);

これがお役に立てば幸いです。幸運を祈ります。

于 2010-06-09T00:40:17.400 に答える
10

古い投稿ですが、今後の参考のために:

この質問とここにあるリンクに触発されて、これらの種類の「悪い」ICC カラー プロファイルを持つ JPEG 画像をサポートする ImageIO 用の JPEGImageReader プラグインを作成しました (「問題」は、ICC プロファイルのレンダリング インテントが Java の ColorConvertOp と互換性がないことです) )。これはプレーンな Java であり、JAI は必要ありません。

ソース コードとリンクされたバイナリ ビルドは、GitHubのTwelveMonkeys プロジェクトから自由に入手できます。

于 2013-04-22T14:13:13.313 に答える
7

私は同じ問題に直面しました。JAI は時代遅れなので使いたがりませんでしたが、それが最短の解決策のようです。

このコードは、sun の ImageIO (高速) を使用して、またはこの問題が発生するいくつかのケースでは、JAI を使用して、InputStream を BufferedImage に変換します。

public static BufferedImage read(InputStream is) throws IOException {
    try {
        // We try it with ImageIO
        return ImageIO.read(ImageIO.createImageInputStream(is));
    } catch (CMMException ex) {
        // If we failed...
        // We reset the inputStream (start from the beginning)
        is.reset();
        // And use JAI
        return JAI.create("stream", SeekableStream.wrapInputStream(is, true)).getAsBufferedImage();
    }
}
于 2012-10-11T16:35:19.807 に答える