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;
}

BufferedImageの代わりに必要な場合、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()ただし、通常はを返すためBufferedImage.TYPE_CUSTOM、を作成できませんので注意してくださいBufferedImage。私の場合、返されたサンプルサイズに従ってタイプを「推測」する必要がありましたimage.getSampleModel().getSampleSize(0)(使用している画像形式がわかっているため)。RenderedImageをに変換するためのより良い方法を知っているなら、BufferedImage私に教えてください:)

于 2012-05-24T13:22:42.727 に答える
0

Apache-Commons Imaging私は(以前のSanselan) の最新バージョンを使用することになりました。Imagingすぐに使用できるTIFFファイルのサポートを提供します(最初は少し問題がありましたが、古いSanselanから新しいCommons Imagingに切り替えることで解決しました)。

自分でリバースエンジニアリングする必要のある機能が少しありました(アスペクト比を維持しながら、指定された幅で単一のサブ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

TIFFファイルをデコードして使用するにはJAIライブラリが必要だと考えるのは正しいですが、それらをインポートしたとしても、実際には使用していません。

これは、 (JAIライブラリから)TIFFDecodeParamオブジェクトを作成し、それを使用してTIFF画像をデコード(および表示)する方法を示す短いチュートリアルです。

また、JAIAPIライブラリも役立つ場合があります。

于 2012-05-16T23:09:21.947 に答える