簡體   English   中英

ImageIO 無法寫入 JPEG 文件

[英]ImageIO not able to write a JPEG file

我有一個 BufferedImage 我正在嘗試寫入一個 jpeg 文件,但我的 Java 程序拋出異常。 我能夠成功地將相同的緩沖區保存為 gif 和 png。 我試過在谷歌上四處尋找解決方案,但無濟於事。

代碼:

   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

OpenJDK沒有原生JPEG編碼器,嘗試使用Sun的JDK,或使用庫(如JAI)

AFAIK,關於“粉紅色調”,Java將JPEG保存為ARGB(仍然具有透明度信息)。 大多數觀眾在打開時假設四個頻道必須對應於CMYK(不是ARGB),因此必須是紅色。

如果將圖像導回到Java,透明度仍然存在。

我有同樣的問題在OpenJDK 7的,我設法通過使用得到這個例外各地imageTypeTYPE_3BYTE_BGR代替TYPE_4BYTE_ABGR使用相同的OpenJDK。

這是一些代碼來說明@Thunder將圖像類型更改為TYPE_3BYTE_BGR的想法

try {
  BufferedImage input = ImageIO.read(new File("input.png"));
  System.out.println("input image type=" + input.getType());
  int width = input.getWidth();
  int height = input.getHeight();
  BufferedImage output = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
  int px[] = new int[width * height];
  input.getRGB(0, 0, width, height, px, 0, width);
  output.setRGB(0, 0, width, height, px, 0, width);
  ImageIO.write(output, "jpg", new File("output.jpg"));
} catch (Exception e) {
  e.printStackTrace();
}

你得到同樣的錯誤

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? 怎么解決這個問題。

2019回答:確保您的BufferedImage沒有Alpha透明度。 JPEG不支持alpha,因此如果您的圖像具有alpha,則ImageIO無法將其寫入JPEG。

使用以下代碼確保您的圖像沒有alpha透明度:

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;
}

當我得到的圖像是RenderedImage時,我有一個變化,而不是復制字節數組,我使用的是Raster ,它是一個矩形圖像表示。

var newBufferedImage = new BufferedImage(
    renderImg.getWidth(),
    renderImg.getHeight(),
    BufferedImage.TYPE_INT_RGB
);
renderImg.copyData(newBufferedImage.getRaster());

根據您的需要,從ColorModel獲取柵格可能會很有趣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM