web-dev-qa-db-ja.com

ImageIOがJPEGファイルを書き込めない

Jpegファイルに書き込もうとしているBufferedImageがありますが、Javaプログラムが例外をスローします。同じバッファーをgifとpngに正常に保存できます。私はGoogleで解決策を探してみましたが、役に立ちませんでした。

コード:

   File outputfile = new File("tiles/" + row + ":" + col + ".jpg");
   try {
       ImageIO.write(mapBufferTiles[row][col], "jpg", outputfile);
   } catch (IOException e) {
        outputfile.delete();
        throw new RuntimeException(e);
   }

例外:

 Exception in thread "main" Java.lang.RuntimeException: javax.imageio.IIOException: Invalid argument to native writeImage
 at MapServer.initMapBuffer(MapServer.Java:90)
 at MapServer.<init>(MapServer.Java:24)
 at MapServer.main(MapServer.Java:118)
 Caused by: javax.imageio.IIOException: Invalid argument to native writeImage
 at com.Sun.imageio.plugins.jpeg.JPEGImageWriter.writeImage(Native Method)
 at com.Sun.imageio.plugins.jpeg.JPEGImageWriter.writeOnThread(JPEGImageWriter.Java:1055)
 at com.Sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.Java:357)
 at javax.imageio.ImageWriter.write(ImageWriter.Java:615)
 at javax.imageio.ImageIO.doWrite(ImageIO.Java:1602)
 at javax.imageio.ImageIO.write(ImageIO.Java:1526)
 at MapServer.initMapBuffer(MapServer.Java:87)
 ... 2 more
51
Karan

OpenJDKにはネイティブJPEGエンコーダーがありません。SunのJDKを使用するか、ライブラリ( [〜#〜] jai [〜#〜] など)を使用してみてください

AFAIK、「ピンクがかった色合い」に関して、JavaはJPEGをARGBとして保存します(まだ透明度情報を含みます)。ほとんどのビューアは、開くときに、4つのチャネルがCMYK(ARGBではない)に対応している必要があると想定しますそして赤の色合い。

ただし、画像をインポートしてJavaに戻しても、透明度はそのまま残ります。

39
Rui Vieira

OpenJDK 7でも同じ問題があり、同じOpenJDKを使用してTYPE_3BYTE_BGRの代わりにTYPE_4BYTE_ABGRimageTypeを使用してこの例外を回避することができました。

32
Thunder

2019の回答:BufferedImageにアルファ透明度がないことを確認してください。 JPEGはアルファをサポートしていないため、画像にアルファがある場合、ImageIOはそれをJPEGに書き込むことができません。

次のコードを使用して、画像にアルファ透明性がないことを確認します。

static BufferedImage ensureOpaque(BufferedImage bi) {
    if (bi.getTransparency() == BufferedImage.OPAQUE)
        return bi;
    int w = bi.getWidth();
    int h = bi.getHeight();
    int[] pixels = new int[w * h];
    bi.getRGB(0, 0, w, h, pixels, 0, w);
    BufferedImage bi2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    bi2.setRGB(0, 0, w, h, pixels, 0, w);
    return bi2;
}
1
Adam Gawne-Cain

同じエラーが発生する

Caused by: javax.imageio.IIOException: Invalid argument to native writeImage
at com.Sun.imageio.plugins.jpeg.JPEGImageWriter.writeImage(Native Method)
at com.Sun.imageio.plugins.jpeg.JPEGImageWriter.writeOnThread(JPEGImageWriter.Java:1055)

サポートされていないカラースペース(私の場合はCYMK)を使用している場合。 JavaでCMYKからRGBに正しく変換する方法を参照してください。 これを解決する方法。

1
rmuller