# 2 Bilder übereinander legen



## AlexLg89 (30. Sep 2008)

Hallo Leute.
Ich möchte gerne 2 Bilder (tif) aufeinander legen. Und zwar soll der Inhalt von dem einen (schwarz/weiß) auf das andere (24Bit) gelegt werden.
Ich habe es schon mit JAI versucht, aber bei mir kommt nur müll raus.
Habt ihr eine Idee, wie ich an die schwarzen Pixel komme und diese auf das andere Bild lege? Oder kann ich irgendwie die weiße Farbe im Bild auf transparent setzen?
Mfg
Alex


----------



## Quaxli (30. Sep 2008)

Muß es ein TIF sein?

Die Farbe auf transparent ändern geht prinzipiell so (getestet mit JPG):

Hauptklasse mit Anzeigefunktionalität:


```
import java.awt.*;
import java.awt.image.*;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.*;

public class Test extends JPanel{
	
	private static final long	serialVersionUID	= 1L;
	BufferedImage buf;
	Image draw;
	
	public static void main(String[] args){
		new Test();
	}
	
	public Test(){
		
		InputStream img_in = this.getClass().getClassLoader().getResourceAsStream("test.jpg");
		
		try {
			buf = ImageIO.read(img_in);
		} catch (IOException e) {}
		
                //Hier findet die Umwandlung statt
		draw = createImage(new FilteredImageSource(buf.getSource(),new MyImageFilter()));
		
		JFrame frame = new JFrame("test");
		frame.setSize(600,300);
		frame.setLocation(100,100);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		frame.add(this);
		
		frame.setVisible(true);
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(draw, 0, 0, this);
		g.dispose();
	}
	
}
```

ImageFilter:


```
import java.awt.Color;
import java.awt.image.RGBImageFilter;

public class MyImageFilter extends RGBImageFilter{

	public int filterRGB(int x, int y, int rgb) {

		Color in = new Color(rgb);
		
		if(rgb == Color.black.getRGB()){
			in = new Color(in.getRed(),in.getGreen(),in.getBlue(),0);
		}

		return in.getRGB();
	}

}
```

Die Änderung in MyImageFilter geht im Prinzip auch mit Bitverschiebung, wenn Dir das lieber ist. Das oben ist der (für mich) bequemere Weg.


----------



## AlexLg89 (1. Okt 2008)

Bin ich einfach zu dumm, oder stimmt da etwas nicht? ^^


```
Exception in thread "main" java.lang.IllegalArgumentException: input == null!
	at javax.imageio.ImageIO.read(Unknown Source)
	at imgTest.Test.<init>(Test.java:26)
	at imgTest.Test.main(Test.java:18)
```

Ich habe die Bilddatei im selben Package wie die Klasse. Oder habe ich da was falsch verstanden?


----------



## Quaxli (1. Okt 2008)

Mit ImageIO kannst Du keine TIFF einlesen. Wenn Du ein bißche googelst findest Du hauptsächlich Verweise auf JAI. 
Wenn Du ein TIFF mit JAI einlesen kannst, solltest Du den Code oben verwenden können.


----------



## Guest (1. Okt 2008)

Wenn ich das Bild mit JAI einlese, dann habe ich z.B. ne RenderedOp. Ich weis aber nicht, wie ich das dann mit dem Programm oben verknüpfen kann.


```
public RenderedImage readImage(String filename){
      
      FileSeekableStream image = null;
      try {
          image = new FileSeekableStream(filename);
      } catch (IOException e) {
          e.printStackTrace();
          System.exit(0);
      }

      ParameterBlock pb = new ParameterBlock();
      pb.add(image);

      RenderedImage imageFromFile = (RenderedImage)JAI.create("tiff", pb);
      
      return imageFromFile ;
}
```


----------



## Quaxli (1. Okt 2008)

Hast Du mal probiert, das RenderedImage in ein BufferedImage zu casten und dann in obigem Beispiel zu verwenden?


----------



## AlexLg89 (1. Okt 2008)

Leider will das nicht klappen.


```
Exception in thread "main" java.lang.ClassCastException: javax.media.jai.RenderedOp cannot be cast to java.awt.image.BufferedImage
	at imgTest.Test.<init>(Test.java:33)
	at imgTest.Test.main(Test.java:27)
```

Der Aufruf:


```
BufferedImage img_in = (BufferedImage)readImage("C:/Temp/savedImage.tif");
      
draw = createImage(new FilteredImageSource(img_in.getSource(),new MyImageFilter()));
```


Die Funktion:


```
public RenderedImage readImage(String filename){
      
      FileSeekableStream image = null;
      try {
          image = new FileSeekableStream(filename);
      } catch (IOException e) {
          e.printStackTrace();
          System.exit(0);
      }

      ParameterBlock pb = new ParameterBlock();
      pb.add(image);

      RenderedImage imageFromFile = JAI.create("tiff", pb);
      
      return imageFromFile;
   }
```


----------



## Quaxli (1. Okt 2008)

Ich hab' mal ein bißchen dran rumgefrickelt und bei mir funzt es jetzt. Das war aber mein erster Versuch mit JAI, evtl. gibt's noch bessere Herangehensweisen:


```
import java.awt.*;
import java.awt.image.*;
import java.awt.image.renderable.ParameterBlock;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import javax.swing.*;

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

public class Test extends JPanel {

	private static final long	serialVersionUID	= 1L;
	BufferedImage							buf;
	Image											draw;

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

	public Test() {
		
		URL img_in = this.getClass().getClassLoader().getResource("test.tif");
		buf = readImage(img_in.getFile());

		draw = createImage(new FilteredImageSource(buf.getSource(),	new MyImageFilter()));

		JFrame frame = new JFrame("test");
		frame.setSize(600, 300);
		frame.setLocation(100, 100);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		frame.add(this);

		frame.setVisible(true);
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(draw, 0, 0, this);
		g.dispose();
	}

	public BufferedImage readImage(String filename) {

		FileSeekableStream image = null;
		try {
			RandomAccessFile raf = new RandomAccessFile(filename,"r");
			System.out.println(raf);
			
			image = new FileSeekableStream(raf);
			
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		ParameterBlock pb = new ParameterBlock();
		pb.add(image);

		RenderedOp ro = JAI.create("tiff", pb, null);

		return ro.getAsBufferedImage();
	}

}
```


----------



## Guest (1. Okt 2008)

Vielen, vielen Dank erstmal.
Hast mir sehr geholfen 
Falls sich noch ein Problem auftut, werd ich nochmal hier posten


----------



## AlexLg89 (1. Okt 2008)

Jetzt muss ich irgendwie noch das draw in einen RenderedOp kriegen.
Könntest du mir da nochmal helfen?


----------



## Quaxli (1. Okt 2008)

Warum? Er zeichnet das doch jetzt wie gewünscht. Wozu noch ein RenderedOp? (Ich bin JAI-Anfänger..)


----------



## Guest (1. Okt 2008)

Selbstverständlich zeichnet er das richtig.
Aber ich muss das Bild mit der Transparenz auf ein Bild ohne Transparenz legen. Das mache ich mit Jai. In der Methode benutze ich 2 RenderedOps. Mit einem RenderedOp und einem Image hat es leider nicht geklappt. Das ist eben mein Problem.


----------



## AlexLg89 (8. Okt 2008)

Keiner ne Idee?


----------



## Quaxli (8. Okt 2008)

Die Methode readImage hat ja auch ein RenderedOp im Bauch. Kannst Du nicht dieses verwenden bzw. zurück geben?


----------



## Alexlg89 (8. Dez 2008)

Leider bringt mir das nicht. Ich müsste den Filter irgendwie auf das RenderedOp anwenden, aber das habe ich nicht hinbekommen. Ich habe noch keine Möglichkeit gefunden, wie ich mit JAI Filter benutzen kann. Jemand ne Idee?


----------



## Alexlg89 (9. Dez 2008)

Ich habs hinbekommen 

public static RenderedOp minImages(RenderedOp image, RenderedOp background){
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.addSource(background);
      return JAI.create("min", pb);
   }


----------

