0

我一直在尝试从许多 BufferedImage 格式的较小图像中绘制一个巨大的图像文件(使用一个大的 BufferedImage 占用的内存比我所拥有的更多),现在我试图通过 ImageWriter 类的 replacePixels-Function 来做到这一点。

然而; 我确实遇到了一个令人费解的错误,即使是广泛的谷歌搜索也无法解决,所以我希望这里有人能告诉我我做错了什么:

javax.imageio.IIOException: Illegal byte order
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriter.locateIFD(TIFFImageWriter.java:2813)
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriter.readIFD(TIFFImageWriter.java:3076)
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriter.canReplacePixels(TIFFImageWriter.java:3099)
at drawingTiles.WorldMapMaker$1.writeImg(WorldMapMaker.java:90)
at drawingTiles.WorldMapMaker$1.run(WorldMapMaker.java:148)
at java.lang.Thread.run(Unknown Source)
javax.imageio.IIOException: Illegal byte order
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriter.locateIFD(TIFFImageWriter.java:2813)
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriter.readIFD(TIFFImageWriter.java:3076)
at com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriter.prepareReplacePixels(TIFFImageWriter.java:3141)
at drawingTiles.WorldMapMaker$1.writeImg(WorldMapMaker.java:104)
at drawingTiles.WorldMapMaker$1.run(WorldMapMaker.java:148)
at java.lang.Thread.run(Unknown Source)

我确实知道字节顺序是什么,但我不知道字节顺序怎么会是非法的。这是我正在使用的功能:

public void writeImg (String path, int startx, int starty, BufferedImage image){
            File output = new File(path);
            ImageOutputStream ios = null;
            try {
                ios = ImageIO.createImageOutputStream(output);
            } catch (IOException e){
                e.printStackTrace();
            }

            Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("TIF");
            ImageWriter writer = (ImageWriter)iter.next();
            writer.setOutput(ios);

            TIFFImageWriteParam writeParam = new TIFFImageWriteParam(Locale.ENGLISH);
            writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);

            try{
                if(writer.canReplacePixels(0)){ // LINE 90
                    System.out.println("True");
                }else{
                    System.out.println("False");
                }
            }catch (IOException e) {
                e.printStackTrace();
            }

            Point destinationOffset = new Point(startx,starty);
            writeParam.setDestinationOffset(destinationOffset);

            try {
                writer.prepareReplacePixels(0, new Rectangle(0, 0, image.getWidth(), image.getHeight())); // LINE 104
                writer.replacePixels(image, writeParam);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
4

1 回答 1

0

如果你看这里,你可以看到TiffImageWriter的源代码。

我在以下代码中看到了这段代码locateIfd()

  long startPos = stream.getStreamPosition();

  stream.seek(headerPosition);
  int byteOrder = stream.readUnsignedShort();
  if (byteOrder == 0x4d4d) {
      stream.setByteOrder(ByteOrder.BIG_ENDIAN);
  } else if (byteOrder == 0x4949) {
      stream.setByteOrder(ByteOrder.LITTLE_ENDIAN);
  } else {
      stream.seek(startPos);
      throw new IIOException("Illegal byte order");
  }

当在该流上调用 setOutput() 时,会设置一个名为 headerPosition 的成员,它是流在该点的当前位置。此代码回溯到该点并查找 Intel 或 Motorola 字节顺序,如果找到其他任何内容则抛出。我猜当 locateIfd 被调用时,您的流在错误的位置。

顺便说一句,图像有多大?我问是因为我在一家拥有Java图像处理库的公司工作,我们的图像模型能够从更复杂的内存模型构建图像而不是连续的,我可以想象制作一个由图像列表组成的复合内存模型存在于虚拟化它们的其他地方。我认为我们目前被迫使用内置的 Tiff 编解码器,我们会和你记忆中的一样,但如果你能忍受 Png,这会奏效。

于 2013-03-15T15:37:09.763 回答