写入TIFF:非法字节顺序

时间:2013-03-15 13:27:44

标签: java image tiff endianness

我一直试图从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();
            }
        }

1 个答案:

答案 0 :(得分: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的成员,该成员是该点在该点的当前位置。此代码寻求回到那一点,并寻找英特尔或摩托罗拉字节顺序和抛出,如果它找到任何其他东西。我猜测当您调用locateIfd时,您的信息流位于错误的位置。

另外,图片有多大?我问,因为我为一家拥有an image processing library Java的公司工作,我们的图像模型能够使用比连续更复杂的内存模型构建图像,我可以想象制作一个由图像列表组成的复合内存模型存在于虚拟化它们的其他地方。我认为我们目前被迫使用内置的Tiff编解码器而且我们会和你记忆中的相同,但是如果你能和Png一起生活,那就行了。