繁体   English   中英

无法使用 Java ImageIO 标准库读写 TIFF 图像文件

[英]Can't read and write a TIFF image file using Java ImageIO standard library

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

谢谢。

如果您不喜欢或因任何原因不能使用 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);

根据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。

我尝试了 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);
        } 
    }
}

Java 仅从 Java 9 版本开始支持 TIFF 格式。 如果您尝试将 ImageIO for TIFF 用于较旧的 Java 版本,则会出现异常。

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

十二猴的 Maven 依赖:

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

我还举例说明了使用十二猴子将多个图像合并到带有页面的单个 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图像并合并为单个。

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

添加 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"));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM