【问题标题】:Can't read and write a TIFF image file using Java ImageIO standard library无法使用 Java ImageIO 标准库读写 TIFF 图像文件
【发布时间】:2009-12-23 19:00:23
【问题描述】:

我不知道如何处理 TIFF 图像,但我无法使用直接的 Java 标准 ImageIO 库读取或写入任何图像。有什么想法吗?

谢谢。

【问题讨论】:

  • 您使用的是 Java SE 吗? Java Advanced Imaging API 支持 TIFF。详情here.
  • 您需要JAI package 来处理 TIFF 文件。显示 TIFF 文件的简单示例:Display a TIF
  • 遇到了同样的问题,将 JAI 的 jar 添加到我的类路径中解决了。无需更改代码中的任何内容,也无需在编译时添加 JAI。只需在运行时添加它,ImageIO.getImageReaders 将能够自行找到它,因为它会扫描类路径,寻找读者。

标签: java tiff javax.imageio


【解决方案1】:

如果您出于任何原因不喜欢或不能使用 JAI,我已经为 ImageIO 编写了一个 TIFF ImageReader 插件,可在 GitHub 上找到。它是纯 Java,不需要任何本机安装,并带有非常友好的开源许可证 (BSD)。

它支持任何基线 TIFF 选项,以及许多标准扩展。从 3.1 版开始,TIFF 插件也支持写入。

在您的类路径中使用正确的 JAR,使用方法可以很简单:

BufferedImage image = ImageIO.read(inputTIFF);
// ...modify image (compose, resize, sharpen, etc)...
ImageIO.write(image, "TIFF", outputTIFF);

【讨论】:

  • HI haraldK 你怎么用这个???我根本不喜欢 JAI,我找不到任何关于如何将 tiff 文件转换为 jpg 的示例。我试过: BufferedImage image = ImageIO.read(new File(inFile)); !ImageIO.write(image, "jpg", new File(outFile)))
  • @delkant 如果您已正确安装所有内容,那应该可以工作。请参阅installation instructions 了解更多详细信息,或者如果您无法使其正常工作,请提交问题(提供完整详细信息)。
【解决方案2】:

根据JEP 262: TIFF Image I/O,从 Java 9 开始,曾经是 JAI 一部分的 TIFF 插件将作为 Java SE 的一部分提供。

这意味着,使用 Java 9 或更高版本,以下代码将正常工作,无需任何额外的导入或依赖项:

BufferedImage image = ImageIO.read(inputTIFF);
// ...modify image (compose, resize, sharpen, etc)...
ImageIO.write(image, "TIFF", outputTIFF);

我还无法验证此插件是否支持非基线 TIFF 风格,但我认为至少应该完全支持基线 TIFF。

【讨论】:

    【解决方案3】:

    我尝试了 JAI,但它对我不起作用。

    你被困在哪里了?以下内容对您有用吗?

    import java.io.File;
    import java.io.FileOutputStream;
    import java.awt.image.RenderedImage;
    import com.sun.image.codec.jpeg.JPEGCodec;
    import com.sun.image.codec.jpeg.JPEGImageEncoder;
    import javax.media.jai.NullOpImage;
    import javax.media.jai.OpImage;
    import com.sun.media.jai.codec.SeekableStream;
    import com.sun.media.jai.codec.FileSeekableStream;
    import com.sun.media.jai.codec.TIFFDecodeParam;
    import com.sun.media.jai.codec.ImageDecoder;
    import com.sun.media.jai.codec.ImageCodec;
    
    public class Main {
        public static void main(String args[]) {
            File file = new File("input.tif");
            try {
                SeekableStream s = new FileSeekableStream(file);
                TIFFDecodeParam param = null;
                ImageDecoder dec = ImageCodec.createImageDecoder("tiff", s, param);
                RenderedImage op = new NullOpImage(dec.decodeAsRenderedImage(0),
                                                   null,
                                                   OpImage.OP_IO_BOUND,
                                                   null);
                FileOutputStream fos = new FileOutputStream("output.jpg");
                JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(fos);
                jpeg.encode(op.getData());
                fos.close();
            }
            catch (java.io.IOException ioe) {
                System.out.println(ioe);
            } 
        }
    }
    

    【讨论】:

    • 一旦你的类路径中有 jai_imageio.jar,你应该可以正常使用 ImageIO API
    • 这是哪个版本的 jar 以及它存储在哪个存储库中?我在 Maven 中查找并找不到它。
    【解决方案4】:

    Java 仅从 Java 9 版本开始支持 TIFF 格式。如果您尝试将 ImageIO 用于 TIFF 到较旧的 Java 版本,它会给您例外。

    如果您也想在早期版本中使用 TIFF,您只需添加 Twelve Monkey 的依赖项即可将 Twelve Monkey 插件与 Java 一起添加。

    十二猴子的Maven依赖:

    <dependency>
       <groupId>com.twelvemonkeys.imageio</groupId>
       <artifactId>imageio-tiff</artifactId>
       <version>3.5</version>
    </dependency>*
    

    我还举了一个例子,使用 Twelve Monkey 将多个图像合并为单个 TIFF,

    BufferedImage b1 = null;
    BufferedImage b2 = null;
    
    TIFFImageReaderSpi SPI = new TIFFImageReaderSpi();
    
    ImageReader imageReader1 = SPI.createReaderInstance();
    ImageInputStream iis1 = ImageIO.createImageInputStream(new File("1.tif"));
    imageReader1.setInput(iis1);
    b1 = imageReader1.read(0); 
    
    ImageReader imageReader2 = SPI.createReaderInstance();
    ImageInputStream iis2 = ImageIO.createImageInputStream(new File("2.tif"));
    imageReader2.setInput(iis2);
    b2 = imageReader2.read(0);
    
    ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next();
    
    writer.setOutput(ImageIO.createImageOutputStream(new File("3.tif")));
    
    ImageWriteParam writeParam = writer.getDefaultWriteParam();
    //writeParam.setTilingMode(ImageWriteParam.MODE_EXPLICIT);
    //writeParam.setCompressionType("Deflate");
    
    writer.prepareWriteSequence(null);
    
    IIOImage i1 = new IIOImage(b1, null, null);
    IIOImage i2 = new IIOImage(b2, null, null);
    
    writer.writeToSequence(i1, writeParam);
    writer.writeToSequence(i2, writeParam);
    
    writer.endWriteSequence();
    writer.dispose();
    

    上面的代码将与Java8一起工作并编写打开两个TIFF图像并合并为一个。

    此外,您可以根据需要使用压缩。只需使用注释行来添加压缩。

    【讨论】:

      【解决方案5】:

      添加 Maven 依赖:

      <dependency>
        <groupId>org.geotoolkit</groupId>
        <artifactId>geotk-coverageio</artifactId>
        <version>3.17</version>
      </dependency>
      

      代码示例:

      import org.geotoolkit.image.io.plugin.RawTiffImageReader;
      
      IIORegistry registry = IIORegistry.getDefaultInstance();   
      registry.registerServiceProvider(new RawTiffImageReader.Spi());            
      
      String[] a = ImageIO.getReaderFileSuffixes();    
      for (int i=0; i<a.length; i++) {
       System.out.println(a[i]);
      }   
      
      BufferedImage image = ImageIO.read(new File("C:\\mypic.tiff"));
      
      ImageIO.write(image, "jpg",new File("C:\\out.jpg"));
      ImageIO.write(image, "gif",new File("C:\\out.gif"));
      ImageIO.write(image, "png",new File("C:\\out.png"));
      ImageIO.write(image, "tif",new File("C:\\out.tiff"));
      

      【讨论】:

      • 恐怕依赖不再起作用了。什么对我有用:com.github.jai-imageiojai-imageio-core1.3.1(我没有用你的整个代码尝试)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多