1

我正在尝试.tif使用最少数量的附加库在 Java 中显示:

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;

import javax.media.jai.widget.*;
import it.geosolutions.imageio.utilities.*;
import it.geosolutions.imageioimpl.plugins.tiff.*;
import com.sun.media.imageioimpl.common.*;

public static void main(String[] args) {
    try {
        File f = new File("image.tif");  
        BufferedImage tif = ImageIO.read(f);  
        ImageIcon ic = new ImageIcon(tif);  
        JFrame frame = new JFrame();  
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);  
        JLabel label = new JLabel(ic);  
        frame.add(label);  
        frame.setVisible(true);  
    } catch (IOException e) {
        e.printStackTrace();
    }
}

我正在使用的库是:

 jai-core-1.1.3.jar
 jai-imageio-1.1.jar
 imageio-ext-tiff.1.1.3.jar
 imageio-ext-utilities.1.1.3.jar

从这里: http: //java.net/projects/imageio-ext(右侧的下载链接)

但是,显示的图像是: 损坏的 tif 这绝对不是原始图像。我所知道的也没有抛出任何错误。此外,原始图像很好,不会改变。

但是,原始代码很小。我实际上并没有使用imageio-ext导入,但是如果没有它们,程序将会失败。我以前也没有用过imageio-ext

请帮忙!我需要能够.tif在不安装软件的情况下使用 Java 中的图像。

4

3 回答 3

2

如果您已经使用了所有 JAI/ImageIO 库,您可能想尝试以下方法(这对我来说很好):

import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageDecoder;

// This function is minimal, you should add exceptions and error handling
public RenderedImage read(String filename)
    FileSeekableStream fss = new FileSeekableStream(filename);
    ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", fss, null);
    RenderedImage image = decoder.decodeAsRenderedImage()
    fss.close();
    return image;
}

如果您需要 aBufferedImage而不是 a RenderedImage,我找到的唯一解决方案是使用此功能:

public static BufferedImage Rendered2Buffered(RenderedImage image) {
    BufferedImage bi = new BufferedImage(image.getWidth(), image.getHeight(), image.getSampleModel().getDataType());
    bi.setData(image.getData());
    return bi;
}

但要小心,image.getSampleModel().getDataType()通常会返回 a BufferedImage.TYPE_CUSTOM,这使得无法BufferedImage创建 !就我而言,我必须根据返回的样本大小“猜测”类型image.getSampleModel().getSampleSize(0)(因为我知道我正在使用的图像格式)。如果您知道将 a 转换为 a 的更好方法RenderedImageBufferedImage请赐教:)

于 2012-05-24T13:22:42.727 回答
0

我最终选择了最新版本的Apache-Commons Imaging(以前的 Sanselan)。 Imaging提供对 TIFF 文件的开箱即用支持(起初我遇到了一点麻烦,但通过从旧的 Sanselan 切换到新的 Commons Imaging 解决了这个问题)。

我必须自己对一些功能进行逆向工程(以指定宽度加载单个 sub-TIFF,同时保持纵横比):

/**
 * Load a scaled sub-TIFF image.  Loads nth sub-image and scales to given width; preserves aspect ratio.
 * 
 * @param fileName String filename
 * @param index Index of sub-TIFF; will throw ArrayIndexOutOfBoundsException if sub-image doesn't exist
 * @param w Desired width of image; height will scale
 * @return Image (BufferedImage)
 * @throws IOException
 * @throws ImageReadException
 */
public static Image loadScaledSubTIFF(String fileName, int index, int w) throws IOException, ImageReadException {
    File imageFile = new File(fileName);
    ByteSourceFile bsf = new ByteSourceFile(imageFile);
    FormatCompliance formatCompliance = FormatCompliance.getDefault();
    TiffReader tiffReader = new TiffReader(true);
    TiffContents contents = tiffReader.readDirectories(bsf, true, formatCompliance);
    TiffDirectory td = contents.directories.get(index);
    Image bi = td.getTiffImage(tiffReader.getByteOrder(), null);
    Object width = td.getFieldValue(new TagInfo("", 256, TiffFieldTypeConstants.FIELD_TYPE_SHORT) {/**/});
    Object height = td.getFieldValue(new TagInfo("", 257, TiffFieldTypeConstants.FIELD_TYPE_SHORT) {/**/});
    int newWidth = w;
    int newHeight = (int) ((newWidth * ((Number)height).doubleValue()) / (((Number)width).doubleValue()));

    bi = bi.getScaledInstance(w, newHeight, java.awt.Image.SCALE_FAST);
    height = null;
    width = null;
    td = null;
    contents = null;
    tiffReader = null;
    formatCompliance = null;
    bsf = null;
    return bi;
}
于 2012-05-24T14:01:41.723 回答
0

您认为您需要 JAI 库来解码和使用 TIFF 文件是正确的,但即使您已导入它们,您实际上并没有使用它们!

这是一个简短的教程,展示了如何创建一个 TIFFDecodeParam 对象(来自 JAI 库),然后使用它来解码(和显示)一个 TIFF 图像。

您可能还会发现JAI API 库也很有用。

于 2012-05-16T23:09:21.947 回答