# TIFF nach BufferedImage wandeln



## reibi (31. Okt 2006)

Hallo Community,

ich möchte ein Multipage TIFF (z.B. mit 5 Seiten) in mehrere BufferedImages umwandeln.

Also zB so:


```
BufferedImage myFirstBI = myMultipagelTIFF.getBufferedImage(1);
```

So einfach gehts leider nicht. Aber vielleicht weiss ja jemand wie sowas geht, oder hat damit schon herumgespielt. 

vielen Dank schon mal

 :roll:


----------



## Wildcard (31. Okt 2006)

Hast du eine Komponente die das TIFF anzeigt? Wenn ja, kannst du dir ein BufferedImage erzeugen, ein Grapics Objekt erzeugen lassen, und die Komponente darauf zeichnen lassen.


----------



## reibi (31. Okt 2006)

Hallo Wildcard,

nee hab praktisch nichts hab nur n TIFF im Dateisystem und brauch n BufferedImage um es zu manipulieren.


----------



## thE_29 (31. Okt 2006)

Bsp Code:


```
/****************************************************************************
   * Methode gibt ein BufferedImage von einem Image zurück
   * @param image Image
   * @return BufferedImage
   ***************************************************************************/
  public static BufferedImage toBufferedImage(Image image)
  {
    //wenn das Bild schon ein BufferedImage ist
    if (image instanceof BufferedImage)
      return (BufferedImage)image;

    // This code ensures that all the pixels in the image are loaded
    image = new ImageIcon(image).getImage();

    // Determine if the image has transparent pixels; for this method's
    // implementation, see e661 Determining If an Image Has Transparent Pixels
    boolean hasAlpha = hasAlpha(image);

    // Create a buffered image with a format that's compatible with the screen
    BufferedImage bimage = null;
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    try {
     // Determine the type of transparency of the new buffered image
     int transparency = Transparency.OPAQUE;
     if (hasAlpha) {
       transparency = Transparency.BITMASK;
     }

     // Create the buffered image
     GraphicsDevice gs = ge.getDefaultScreenDevice();
     GraphicsConfiguration gc = gs.getDefaultConfiguration();
     bimage = gc.createCompatibleImage(image.getWidth(null), image.getHeight(null), transparency);
   }
   catch (HeadlessException e)
   {
      // The system does not have a screen
      e.printStackTrace(System.out);
    }
    if (bimage == null) {
      // Create a buffered image using the default color model
      int type = BufferedImage.TYPE_INT_RGB;
      if (hasAlpha) {
        type = BufferedImage.TYPE_INT_ARGB;
      }
      bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
    }
    // Copy image to buffered image
    Graphics g = bimage.createGraphics();
    // Paint the image onto the buffered image
    g.drawImage(image, 0, 0, null);
    g.dispose();
    return bimage;
  }


  /**************************************************************************
   * This method returns true if the specified image has transparent pixels
   * @param image Image
   * @return boolean
   *************************************************************************/
  private static boolean hasAlpha(Image image)
  {
    // If buffered image, the color model is readily available
    if (image instanceof BufferedImage) {
      BufferedImage bimage = (BufferedImage)image;
      return bimage.getColorModel().hasAlpha();
    }

    // Use a pixel grabber to retrieve the image's color model;
    // grabbing a single pixel is usually sufficient
    PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
    try {
      pg.grabPixels();
    } catch (InterruptedException e)
    {
      e.printStackTrace(System.out);
    }
    // Get the image's color model
    ColorModel cm = pg.getColorModel();
    return cm.hasAlpha();
  }
```


----------



## reibi (31. Okt 2006)

Hallo thE_29,

danke für Deinen Post; ich hab aber leider kein OBJ vom Typ Image.

Was ich ausschliesslich habe ist ein TIF auf dem FileSystem.

;-)


----------



## Wildcard (31. Okt 2006)

Such mal nach Bibliotheken die TIFFs verarbeiten können. Gibt's bestimmt was.


----------



## reibi (31. Okt 2006)

Hab da grad was jmf --> "Java Media Framework"

Irgendwie liefert mir das aber auch kein Image oder BufferedImage

:-(


----------



## The_S (31. Okt 2006)

Ist es denn so schwer Google zu benutzen? Schau mal auf java.sun.com nach JAI. Damit sollte das gehen.


----------



## thE_29 (31. Okt 2006)

Hast du den eine grafische Oberfläche? 

Oder ist das ein reines kommandline Tool!

Ansonsten kannst du einen JDialog auf Position -1000,-1000 setzen und dort abzeichen


----------



## reibi (31. Okt 2006)

nee hab keine Oberfläche


----------



## thE_29 (31. Okt 2006)

Mhmm..

Na das ist dumm...

Was für ein Objekt ist diese Tiff überhaupt?!

Erbt das nicht von Image? Oder gibts da keine toImage Methode?


----------



## reibi (31. Okt 2006)

Also im jmf Beispiel läuft das so:


```
ImageDecoder dec=ImageCodec.createImageDecoder("tiff", s, param);
```

Image decoder ist von dem hier abgeleitet:

All Known Implementing Classes:
    ImageDecoderImpl 

hab ich von hier:

http://www.nvcc.edu/home/jdileo/JavaDocs/JAI1.0.1/com/sun/media/jai/codec/ImageDecoder.html

Alles was man da raushohlen kann hab ich schon ausprobiert, kommt aber nix raus was Image oder BufferdImage heisst

...


----------



## The_S (31. Okt 2006)

@thE_29

Ich glaube reibi meint das Bildformat TIFF. Er möchte praktisch ein Tiff in seine Applikation laden


----------



## reibi (31. Okt 2006)

Achso Code soll so praktisch sein:


```
ImageDecoder dec=ImageCodec.createImageDecoder("tiff", myFileStream, null);
```


----------



## reibi (31. Okt 2006)

Hallo,

ja das will ich !!
zB Bild namens: "familienFoto.tif"

Ist TIF mehrdeutig?


----------



## thE_29 (31. Okt 2006)

You can grab the TIFF/GIF file format from www.wotsit.org. After decoding the 
TIFF, you can convert the raw byte[] stream to Image.


-->: public Image createImage(byte[] imagedata)

oder public abstract Image createImage(byte[] imagedata,
                                  int imageoffset,
                                  int imagelength)


Beides in der Toolkit Klasse 

Und von Image kannst du dann meinen Source nehmen um es in BufferedImage zu konvertieren


----------



## reibi (31. Okt 2006)

@thE_29

Ich war auf dieser Seite :: Weiss aber nicht so richtig was Du damit aussagen willst.

Gibts dort ein neues Framework downZuLoaden? Mit welchem man TIFs lesen kann?

oder soll man dort das TIF hochladen und man bekommt ne BufferedImage-Instanz zurück?


----------



## thE_29 (31. Okt 2006)

Die Seite ist einfach egal..

Diesen Text habe ich gefunden..

Mach einfach was da steht und vergiß die URL!


----------



## Roar (31. Okt 2006)

thE_29 hat gesagt.:
			
		

> Mach einfach was da steht und vergiß die URL!


da steht ich soll auf die seite gehen ..1^^

achja zum thema: @frager: jimi und jai sollten beide tiffs lesen können.


----------



## reibi (31. Okt 2006)

Hallo thE_29,

Bei mir steht da jetzt auch mehr:


```
public Image createImage(byte[] imagedata)
```

und zweitens:


```
public abstract Image createImage(byte[] imagedata,
int imageoffset,
int imagelength)
```

Welche Klasse soll den das machen?

Konnte mir vorstellen das Image oder BufferedImage das machen.

Aber falsch, die machen das nicht

Die Methode im Code 2 ist sogar abstract. 

Also wie meinst Du denn das genau?
;-)


----------



## reibi (31. Okt 2006)

@Roar

Ich bin Frager!

jai ist Teil von jmf(welches ich benutze) denke ich. Hab da noch nix brauchbares gefunden. Also alles was TIF liesst ...liefert mir direkt und indirekt kein Image oder BufferedImage.

und wegen jimi: weiss ich nicht wo ichs downloaden soll; hab darüber auch schon etwas im Netz gelesen.


----------



## Roar (31. Okt 2006)

jai is eigentlich kein teil von jmf,
jimi findest du hier: http://java.sun.com/products/jimi/


----------



## thE_29 (31. Okt 2006)

Wo stand jemals das man auf die URL gehen soll??

Ja man soll sich ein Bsp Bild holen, aber da steht nix von einer Lösung..


Desweiteren wer lesen kann ist klar im Vorteil 

Die 2 Methoden sind beide in der Toolkit Klasse (habe ich vorher auch schon hingeschrieben).

Und laut dieser Aussage, kann man sich vom decodierten Tif Bild den byte[] Stream holen!

Mit der Toolkit.getDefaultToolkit().createImage(byte[]) kann man dann ein Bild erzeugen lassen!


Desweiteren ist die eine Methode abstract, weil die createImage(byte[]) intern auch die abstrakte Methode aufruft!

Aber abstract Methoden die in Java Standardklassen sind und keine interfaces sind, kannst du ruig aufrufen, denn die gibts dann schon 

read und write im Input/Outputstream sind ja auch abstract und die funken


----------



## Roar (31. Okt 2006)

thE: von den createImage() methoden hat er nix, solange er das tiff bild nicht dekodiert hat, und dafür soll er auf wotsit.org gehen, sich dort die dokumentatino dazu durchlesen und das dekodieren selber schreiben, oder ist schlau und benutzt einfach code, den schon andere schlaue menschen dafür geschrieben haben :-B


----------



## reibi (31. Okt 2006)

@Roar

wegen jai:
Dachte mir das is so:
Teile vom jmf heissen zB so:

import javax.media.jai.NullOpImage;
import javax.media.jai.OpImage;
import javax.media.jai.widget.ScrollingImagePanel;

jimi find ich irgendwie auch kein Beispiel dazu
;-)


----------



## reibi (31. Okt 2006)

@thE_29

Ja das stimmt allerdings: Ich sollte mal lesen lernen.

Also dem geh ich grad mal nach: Muss mal sehen ob sich der TIF-Leser vom jmf-jai irgendwie überreden lassen will mir ein byteArray auszuspucken ;-)


----------



## thE_29 (31. Okt 2006)

Zonk:

http://www.java-forum.org/de/viewtopic.php?p=230929#230929

Da hat er schon nen Decoder ^^

Dann nimmt er dec.getInputStream() und speichert das in ein byte[] und wandelt das mit der Toolkit Klasse in ein Image und mit meinem Code in ein BufferedImage..

Ich verstehe euer Problem net :bae:


----------



## reibi (31. Okt 2006)

@thE_29

Das isses fast!

Problem ist nur dass der Decoder immer noch alle Seiten des TIFs repräsentiert!

womit sage ich denn nun welche Seite ich als byte[] haben will..
so gesehen gibt er mir alle !

Aber wir kommen dem Problem näher ... ich sehe schon.

Danke dafür erstmal ;-)


----------



## thE_29 (31. Okt 2006)

Naja, ich würde alles zuerst in eine riesen BufferedImage machen und dann rausrechnen...

Das machst du indem du dir den Raster holst! 

Jetzt müsstest du halt wissen von welchen Pixeln an (also wie groß) die Bilder sind!

Mit dem Raster holst du dir die einzelnen Pixeln und schreibst die auf ein neues BufferedImage ^^ (new BufferedImage... und getRaster())

Schon hast du alles! Müsstest halt nur wissen wie groß die Bilder sind!


PS.: Das ganze wird aber immens an Speicher fressen 

PPS.: hier arbeite ich mit rastern: http://www.java-forum.org/de/viewtopic.php?p=203567#203567 musst sie halt setzen auf das andere Bild


----------



## Roar (31. Okt 2006)

reibi hat gesagt.:
			
		

> @Roar
> 
> wegen jai:
> Dachte mir das is so:
> ...



ahso, aha, naja kann sei ndass das da mit dbei ist, ich hab mir jai nur seperat runtergeladen ohne jmf da dacht ich


----------



## thE_29 (1. Nov 2006)

Vergiß das mit dem byte Stream und das Image to BufferedImage!

Du kannst gleich sagen: dec.decodeAsRenderedImage()

Und hier holst du dir den Raster!

Das ist schon ein Rendered/BufferedImage und damit kannst du gleich arbeiten (auch via ImageIO.write speichern)


----------



## reibi (1. Nov 2006)

Hallo thE_29,

hab das gestern Abend noch gemacht; aber danke:

funktioniert trozdem nicht!!!
Ich krieg n schrazes Bild zurück; vielleicht weisst Du ja warum:

hier der code:


```
RenderedImage myRI=myDecoder.decodeAsRenderedImage(1);
BufferedImage myBI = new BufferedImage(myRI.getWidth(), myRI.getHeight(), BufferedImage.TYPE_INT_RGB);
		
Raster myRaster = myRI.getData(); 		
		
myBI.setData(myRaster);
		
//von mir		
ImageTools.saveBufferedImageAsJPG(myBI, "C:\\zuHallo.jpg");
```

und war gibt dazu noch ne exception welche von hier kommt:

```
myBI.setData(myRaster);
```

und sieht so aus:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1216
	at java.awt.image.SinglePixelPackedSampleModel.setPixels(Unknown Source)
	at java.awt.image.WritableRaster.setPixels(Unknown Source)
	at sun.awt.image.SunWritableRaster.setPixels(Unknown Source)
	at java.awt.image.BufferedImage.setData(Unknown Source)
	at ch.visana.ok.rbm.tests.independent.MultiPageRead.main(MultiPageRead.java:91)


----------



## reibi (1. Nov 2006)

Und zwar brauch ich das ganze totzdem als BufferedImage... weil ich das noch weiterverarbeiten muss. Also einfach abspeichern als RenderedImage nützt mir nicht viel.

;-)


----------



## thE_29 (1. Nov 2006)

Wie speicherst du den dieses Bild...

Nimm ImageIO.write(myRI, "png", new File("C:\\test.png"));

Bei mir klappt das so einwandfrei!

Jedenfalls, das was du willst, sieht so aus:


```
Raster r = dec.decodeAsRaster();
      int width = r.getWidth();
      int height = r.getHeight();
      BufferedImage bimg = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
      WritableRaster b = bimg.getRaster();
      double pixels[] = new double[4];
      for(int x  = 0; x != width; x++)
      {
        for(int y = 0; y != height; y++)
        {
          r.getPixel(x,y,pixels);
          b.setPixel(x,y,pixels);
        }
      }      
      ImageIO.write(bimg, "png", new File("C:\\test_out2.png"));
```


----------



## reibi (1. Nov 2006)

Hallo:

Habs eins zu eins kopiert--> geht nicht!

Vielleicht liegts dara dass ich das ganze mit nem Multipage-TIF mache und Du nicht?
Welchen Dateityp liesst Du bei beginn ein? (JPG, PNG, GIF MP-TIFF oder einzel-TIF)

Kann das sein?


----------



## thE_29 (2. Nov 2006)

Ein TIF das 6900x7200 hat! Bei dem klappt das auch nüscht.. (aber direkt Speichern, also dec.decodeAsRendereredImage() und dann mit ImageIO.write klappt)

Und das andere TIF mit 400x500 klappt immer!


----------



## reibi (2. Nov 2006)

Das is komisch; meines hat 1200x1600 und hat 5 Seiten.


----------



## thE_29 (2. Nov 2006)

Wenn du es gleich via ImageIO.write abspeicherst (also mit dec.decodeAsRend..) ist das File dann okay?


----------



## reibi (2. Nov 2006)

nee isses nich! es ist schwarz, das Bild;-(


----------



## thE_29 (2. Nov 2006)

Also das klappt bei mir auch mit dem Riesebild was 1.8 MB hat!

Kannst du das Bild irgendwo upload zum Testen?


Ädit: sehs erst jetzt (man sollte halt doch in die API schaun)

Da gibts ja so feine Befehle wie: 

ImageDecoder.getNumPages() -> liefert die gesamte Seitenanzahl!

Und decodeAsRenderedImage(int page) 

decodeAsRaster(int page) 


Tadaaa   Probier mal indem du ne Seite angibst!


----------



## reibi (2. Nov 2006)

HU ... ich probier das immer schon mit der Seite. Also ich hab ja Javadoc vorher angeschaut ;-) und habs auch immer so eingesetzt: decodeAsRenderedImage(int page)


----------



## thE_29 (2. Nov 2006)

Mhmm...

Kannst du den das Bild wo hinstellen?!

Und gibt es dieses JAI auch irgendwo als Paketversion und net als Installationssatz zum Runterladen?!


----------



## reibi (2. Nov 2006)

Moment:

Also:

Hier isses
http://www.powerdesign.ch/component/option,com_docman/task,cat_view/gid,15/Itemid,7/

und zar weiss ich nich mehr wo und wie ichs runtergeladen habe ... deshalb kannstes hier runterziehen.

Danke ;-)


----------



## thE_29 (2. Nov 2006)

Fehlen da nicht noch 2 dlls und das Tif Bild zum Testen?


----------



## reibi (2. Nov 2006)

Versteh nicht ? dlls? Das ist doch MS-WindowsZeugs


----------



## reibi (2. Nov 2006)

Aber: Ich würde mich gerne noch mal n konkreten Beispiel widmen:

Anderer Ansatz(ich hab jetzt min 3): Und zwar will ich ja insgesamt aus einer TIf-Seite ein BufferedImage machen. Der Weg dahin sollte eigentlich so gehen --> Krieg aber nur n Weisses Bild:


```
RenderedImage myRI=myDecoder.decodeAsRenderedImage(1);


ImageTypeSpecifier myITS = ImageTypeSpecifier.createFromRenderedImage(myRI);
//oder so:
//ImageTypeSpecifier myITS = new ImageTypeSpecifier(myRI);
BufferedImage myBI = myITS.createBufferedImage(myRI.getWidth(), myRI.getHeight());
//Das is von mir! läuft aber drin über ImageIO.write
ImageTools.saveBufferedImageAsJPG(myBI, "C:\\zuHallo.jpg");
```

Vielleicht weiss ja jemand warum der mir hier n weisses Bild liefert?


----------



## reibi (2. Nov 2006)

@thE_29:
Übrigenz geht das hier jetzt:


```
ImageIO.write(myDecoder.decodeAsRenderedImage(1), "jpg", new File("c:\\neu.jpg"));
```


----------



## thE_29 (2. Nov 2006)

Ich mache es immer mit png und bei mir geht das!

Nur habe ich kein mehrseitiges TIF!


Desweiteren braucht man diese 2 DLLs nicht um JAI laufen zu lassen?!

Bei mir hat der 2 DLL´s installiert (daheim) als ich dieses JAI Setup gemacht habe!


----------



## reibi (2. Nov 2006)

Ich hab kein Setup gemacht, sondern nur die 2 Files in den Classpath gepackt. Ausserdem soll das ganze ja auf Linux laufen. Da kennt ja keiner DLLs.


----------



## kaie (2. Nov 2006)

Auch auf die Gefahr hin, dass ich hier irgendwo im Thread etwas übersehen habe und dieser Link schon gepostet wurde: hast Du schonmal dieses Codebeispiel von der Sun-Seite ausprobiert?


----------



## reibi (2. Nov 2006)

@kaie

Jep, hab ich schon ausprobiert. Das Problem ist das es mir nur ein RenderedImage liefert. Ich brauche aber ein BufferedImage.


----------



## KSG9|sebastian (2. Nov 2006)

dann schreib es mit ImageIO in nen OutputStream und lad es als BufferedImage?


----------



## reibi (2. Nov 2006)

Also wie das in nen Outputstream geht weiss ich. Nur Wie schreib ichs dann wiederum in das BufferedImage?


----------



## KSG9|sebastian (2. Nov 2006)

Kannst doch die bytes "laden" und damit das BufferedImage generieren


----------



## reibi (2. Nov 2006)

Das versteh ich nicht! Haste mal n kurzes Beispiel?


----------



## Guest (2. Nov 2006)

Was funktioniert denn bitte nicht, wenn Du es einfach auf ein neues BufferedImage draufzeichnest?

```
public BufferedImage wandleBild( Image i )
{
  BufferedImage bi = new BufferedImage( i.getWidth(null), i.getHeight(null), BufferedImage.TYPE_INT_RGB );
  bi.getGraphics().drawImage(i,0,0,null);
  return bi;
}
```
Ich fürchte, ich versteh das Problem immer noch nicht... :bahnhof:


----------



## reibi (2. Nov 2006)

Lieber Gast: Ich kann Doch nicht draufzeichnen, da ich nichts habe was nicht wenigstens ein Image ist!!! Ich habe lediglich ein RenderedImage und dieses ist nicht vom Typ Image!!


----------



## kaie (2. Nov 2006)

Das folgende Beispiel funktioniert bei mir ohne Probleme - nur leider habe ich nur TIFFs mit einer Seite. Kannst Du nicht mal Deine Datei zum Testen zur Verfügung stellen? Probier mal, ob das Laden hiermit klappt:


```
import java.awt.image.*;
import java.io.*;

import javax.media.jai.*;
import javax.swing.*;

import com.sun.media.jai.codec.*;

public class TifConverter
{
    public static void main(String[] args) throws Exception
    {
        BufferedImage bi = holeSeite("c:/test.tif",0);
        JFrame f = new JFrame();
        f.add(new JButton(new ImageIcon(bi)));
        f.pack();
        f.setVisible(true);
    }

    public static BufferedImage holeSeite( String dateiname, int seite ) throws Exception
    {
        SeekableStream s = new FileSeekableStream( new File(dateiname) );
        ImageDecoder d = ImageCodec.createImageDecoder("tiff", s, null);
        System.out.println("Anzahl Seiten: "+ d.getNumPages());
        RenderedImage op = new NullOpImage(d
                .decodeAsRenderedImage(seite), null, OpImage.OP_IO_BOUND,
                null);
        BufferedImage bi = new BufferedImage(op.getWidth(),op.getHeight(),BufferedImage.TYPE_INT_RGB);
        op.copyData(bi.getRaster());
        return bi;
    }
}
```


----------



## thE_29 (3. Nov 2006)

@reibi: man hat auf der Sun Seite ja auch ein eigenes Installding für Linux und da sind .so (sind dlls für Linux) dabei!

Aber vielleicht gehts auch ohne!

Desweiteren wenn man Bytes hat kann man sich ja ein Bild via dem Toolkit (schon vergessen, steht vor 2 Seiten?!) erstellen lassen!

Toolkit.createImage(byte[]);


----------



## reibi (3. Nov 2006)

@kaie

Habs eins zu eins kopiert! ---> GEHT NICHT!

er wirf das hier

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
	at com.sun.media.jai.util.ImageUtil.copyRaster(ImageUtil.java:274)
	at javax.media.jai.PlanarImage.copyData(PlanarImage.java:2350)
	at TifConverter.holeSeite(TifConverter.java:33)
	at TifConverter.main(TifConverter.java:15)

bei dem hier: op.copyData(bi.getRaster()); 

Langsam zweifel ich an mir selbst! Ich hätte doch lieber Förster werden sollen! ;-)


----------



## thE_29 (3. Nov 2006)

Kannst du dein Bild nicht wo uploaden?!


----------



## reibi (3. Nov 2006)

@thE_29: mir kommt da noch ne Idee mit deinem:

Toolkit.createImage(byte[]);

und so 2 sachen: 4 Seiten vorher...

und

@Alle : Danke das Ihr Euch alle meinem Problem annehmt. ;-)


----------



## thE_29 (3. Nov 2006)

Und falls du keinen Webspace hast oder so, lads hier up: http://www.rapidshare.de/


----------



## reibi (3. Nov 2006)

@thE_29

Hier isses:
http://www.powerdesign.ch/component/option,com_docman/task,cat_view/gid,15/Itemid,7

und zwar heisst es MultipageTiff


----------



## KSG9|sebastian (3. Nov 2006)

```
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.media.jai.NullOpImage;
import javax.media.jai.OpImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

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


public class Test extends JFrame {

	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = 2036333296087078136L;


	public Test() throws IOException {
		super("TIFF Example");
		super.setBounds(0, 0, 500, 500);
		BufferedImage bimg = getImage(1);
		JLabel jl = new JLabel();
		jl.setIcon(new ImageIcon(bimg));
		super.add(jl, BorderLayout.CENTER);
		super.setVisible(true);
	}

	public BufferedImage getImage(int number) throws IOException {
		// unique identifier for temp file
		String uniqueIdentifier = String.valueOf(System.currentTimeMillis());
		// complete filename
		String fileName = "tmp-image-" + uniqueIdentifier;
		// create a temp file
		File tempFile = File.createTempFile(fileName, ".tmp");
		// set deleteOnExit(), if an exception occures
		tempFile.deleteOnExit();
		
		SeekableStream s = new FileSeekableStream(new File("blub.tif"));
		ImageDecoder d = ImageCodec.createImageDecoder("tiff", s, null);
		System.out.println("Anzahl Seiten: " + d.getNumPages());
		RenderedImage op = new NullOpImage(d.decodeAsRenderedImage(number),
				null, OpImage.OP_IO_BOUND, null);
		
		// write image
		ImageIO.write(op, "jpg", tempFile);
		// read image
		BufferedImage buffImg = ImageIO.read(tempFile);
		// delete tempfile
		tempFile.delete();	
		
		return buffImg;
	}


	public static void main(String[] args) throws IOException {
		new Test();

	}
}
```
das tut bei mir mit deinem tif bild..
problem ist folgendes:
Bei älteren TIFFs welche JPG-Bilder mit nem älteren Codec enthalten spackt JAI ab und kann das Bild nicht auslesen.

Edit:
Auch die TIFFS sind 0-basiert, d.h. getImage(0) liefert Bild 1, getImage(1) liefert Bild 2...

Edit #2:
Für den Teil

```
ImageDecoder d = ImageCodec.createImageDecoder("tiff", s, null);
		System.out.println("Anzahl Seiten: " + d.getNumPages());
		RenderedImage op = new NullOpImage(d.decodeAsRenderedImage(number),
				null, OpImage.OP_IO_BOUND, null);
```
gibts ne bessere Lösung welche nicht deprecated ist. Musst mal schauen, irgendwo auf der Sun-Site oder per Google findest du das entsprechende Codeschnippsel.


----------



## thE_29 (3. Nov 2006)

```
String dateiname = "C:\\uid0500301.tif";
    SeekableStream s = new FileSeekableStream( new File(dateiname) );
    ImageDecoder d = ImageCodec.createImageDecoder("tiff", s, null);
    System.out.println("Anzahl Seiten: "+ d.getNumPages());  
    ImageIO.write(d.decodeAsRenderedImage(0),"jpg",new File("C:\\test_out.jpg"));
    ImageIO.write(d.decodeAsRenderedImage(1),"jpg",new File("C:\\test_out2.jpg"));
```

Läuft bei mir einwandfrei und erstellt die Bilder!


----------



## thE_29 (3. Nov 2006)

Und hier der Code fürs BufferedImage


```
String dateiname = "C:\\uid0500301.tif";
    SeekableStream s = new FileSeekableStream( new File(dateiname) );
    ImageDecoder d = ImageCodec.createImageDecoder("tiff", s, null);
    System.out.println("Anzahl Seiten: "+ d.getNumPages());
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    ImageIO.write(d.decodeAsRenderedImage(0),"png",stream);
    Image img = Toolkit.getDefaultToolkit().createImage(stream.toByteArray());
    JFrame testFrame = new JFrame();
    testFrame.getContentPane().add(new JLabel(new ImageIcon(img)));
    testFrame.pack();
    testFrame.setLocationRelativeTo(null);
    testFrame.setVisible(true);
```

Ich habs mal anzeigen lassen, obs auch geht!

Und du nimmst jetzt den Source von Seite 1 wo ich Image in BufferedImage konvertiere und schon hast dein Ergebnis 



Nachtrag: Ich hoffe jetzt haben wirs dann endlich :bae: (mit dem Image img den Code dann aufrufen: http://www.java-forum.org/de/viewtopic.php?p=230914#230914 )


----------



## thE_29 (3. Nov 2006)

Nachtrag 2: @KSG warum ein TempFile wenn auch das geht?


```
String dateiname = "C:\\uid0500301.tif";
    SeekableStream s = new FileSeekableStream( new File(dateiname) );
    ImageDecoder d = ImageCodec.createImageDecoder("tiff", s, null);
    System.out.println("Anzahl Seiten: "+ d.getNumPages());
    ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
    ImageIO.write(d.decodeAsRenderedImage(0),"png",stream);
    ByteArrayInputStream in = new ByteArrayInputStream(stream.toByteArray());
    BufferedImage bimg = ImageIO.read(in);
```



Glaube das ist die "eleganteste" Lösung!

Kein TempFile und kein unnötiges Hin und her konvertieren


----------



## KSG9|sebastian (3. Nov 2006)

Tempfile war nur ne schnelle (pfusch)Lösung weil die Funktion copyData vom RenderedImage nicht funktioniert. Über nen ByteArray isses besser, das hab ich ja auch schon auf Seite 4 vorgeschlagen


----------



## thE_29 (3. Nov 2006)

Das mit dem byte array habe ich schon auf Seite 2 gesagt


----------



## KSG9|sebastian (3. Nov 2006)

ja ich weiß  war ja auch ein hinweise meinerseits


----------



## reibi (3. Nov 2006)

@thE_29:

ES LÄUFT !!! ;-)

Vielen Dank: Dein letztes Beispiel (03. 11. 2006, 10:16) hat gefunzt. Weiss auch nicht was da anders ist als ich das schon ausprobiert hab. Habe ja vorgestern schon mal versucht einn Stream zu hohlen und ihn wieder zu schreiben. Damals liefs nicht; jetzt schon.

naja egal vielen Dank trotzdem

@Alle:
Vielen Dank für die nun bald 6 Seiten Forum. Letztlich hats ja doch noch geklappt.


----------



## Sharpner (17. Nov 2006)

ich haette nachtraeglich noch ne frage, 
kann man die Qualitaet des Jpegs auf diese Art beeinflussen?
Is ja aktuell etwa 75% Kompressionsrate.. wie kann man 100% oder so machen?
mfg
Sharpner


----------

