# BufferedImage => Byte[] => BufferedImage



## javaboon (4. April 2010)

Abend,
ich hab mal ne Frage. Suche schon seit langem einen weg nen Bild in Form eines BufferedImages über Socket zu versenden. Jetzt fang ich nochmal von vorne an. Doch nichtmal dieser Codeschnipsel funktioniert:
		BufferedImage srcImage = ImageIO.read(new File("c:/winter.jpg"));
		int i = 0;
		byte[] imageData = ((DataBufferByte) srcImage.getData().getDataBuffer()).getData();
		BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageData));
		ImageIO.write(image, "jpeg", new File("C:/bla.jpg"));

Den Fehler dürftet ihr kennen, ich komm nicht dahinter. Trotdem mal die Fehlermeldung:

Exception in thread "main" java.lang.IllegalArgumentException: im == null!
	at javax.imageio.ImageIO.write(Unknown Source)
	at javax.imageio.ImageIO.write(Unknown Source)
	at virclient.main(virclient.java:20)

Schonmal vielen Dank


----------



## zeja (4. April 2010)

Warum castest du denn auf DataBufferByte wo du dir gar nicht sicher sein kannst, dass es sich um einen solche handelt?

Korrekt wäre es, das Bild mit ImageIO.write in einen ByteArrayOutputStream zu schreiben. Von dem kannst du dann das byte-Array erfragen und das ganze über den ByteArrayInputStream wieder auslesen.

Wenn du direkt die Datei hast, kannst du allerdings auch ohne dem Umweg über das BufferedImage einfach die Datei in ein ByteArray einlesen.


----------



## javaboon (4. April 2010)

mit der zeit fang ich an zu verzweifeln^^
den code hab ich einfach aus dem forum hier genommen in der hoffnung es t so...
wie kann ich mir das vorstelle?
fürn codeasuschnitt wär ich sehr dankbar ;D


----------



## Kai008 (4. April 2010)

Suche mal nach "ScreenProvider", da gibt es ein Beispiel am Ende des Threads, welches angeblich auch schneller als ImageIO ist.


----------



## javaboon (4. April 2010)

dann noch eine ganz blöde frage
wieso wird bei mir in eclipse das 

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

und alle dazugehörigen codes als falsch markiert?


----------



## Kai008 (4. April 2010)

Weil man auf die Klassen im allgemeinen besser nicht zugreifen sollte, weil sie nicht offiziell gesupported werden. Da sich aber niemand daran hält kannst du das ignorieren, unter Property kannst du auch irgendwo einstellen, wann ein Fehler, eine Wahnung angezeigt oder wann es ignoriert werden soll.


----------



## javaboon (5. April 2010)

es tut mir leid aber es geht immer noch nichts
ich versteh nur nicht warum
habs 1:1 aus dem beitrag kopiert
hier die fehlermeldung für DelegationServer:

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
	RemotePOATie cannot be resolved to a type
	RemotePOATie cannot be resolved to a type
	The method object_to_string(Object) in the type ORB is not applicable for the arguments (Remote)

	at DelegationServer.main(DelegationServer.java:28)

und für den GUIClient:

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
	The method dump(int, int, int[]) is undefined for the type Remote
	RemoteHelper cannot be resolved

	at GUIClient.<init>(GUIClient.java:65)
	at GUIClient.main(GUIClient.java:93)

*edit
auch versteh ich nicht wie das funktionieren sollte, es wird weder ne ip noch nen port benötigt...


----------



## Matthias Reitinger (5. April 2010)

Hallo,

zeja meinte wohl sowas in der Art:

```
package de.tutorials.reima.examples;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import javax.imageio.ImageIO;

public class ImageTransfer {
	public static void main(String[] args) {
		Thread serverThread = new Thread(new Server());
		serverThread.start();
		
		try {
			BufferedImage image = ImageIO.read(new File("sent.png"));
			Socket socket = new Socket(InetAddress.getLocalHost(), 4242);
			ImageIO.write(image, "png", socket.getOutputStream());
			serverThread.join();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static class Server implements Runnable {
		@Override
		public void run() {
			try {
				ServerSocket socket = new ServerSocket(4242);
				Socket client = socket.accept();
				BufferedImage image = ImageIO.read(client.getInputStream());
				ImageIO.write(image, "png", new File("received.png"));
				client.close();
				socket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}		
	}
}
```

Grüße,
Matthias


----------



## Kai008 (5. April 2010)

Hier nochmal zur Vereinfachung der Link: http://www.tutorials.de/forum/java/...g-war-remote-anwendung-corba.html#post1353824
Ich sagte, du sollst das Beispiel am Ende des Threads nehmen, mit einen Wort das von Tom. Cobra kenne ich nur vom hören, aber ich denke du wirst dafür eine Lib. brauchen.

Dort wartet der Server in Zeile 92 auf ankommende Verbindungen an Port 4711, und der Client baut in Zeile 30 eine Verbindung auf. Falls du vorhast eine RDC-Anwendung zu schreiben denke daran, dass es aufgrund der verschoben dargestellten Titelleiste des Clienten auf einen Rechner (außer du emulierst, wie er gesagt hat) nicht richtig testbar sein wird.


----------



## javaboon (5. April 2010)

danke 
ich habs abe immer noch nicht
nun bei beiden eine ähnliche fehlermeldung, bei ScreenConsumer:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 

	at ScreenConsumer.main(ScreenConsumer.java:22)

und bei ScreenProvider:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 

	at ScreenProvider.main(ScreenProvider.java:44)


----------



## Kai008 (5. April 2010)

Das kann ich mir irgendwie nicht vorstellen, in beiden Fällen ist dort eine schließende Klammer, und die Formation ist absolut korrekt. Kontrolliere besser noch mal, ob sich bei dir die Zeilen irgendwie verschoben habe, und der Trace auf eine andere zeigt.


----------



## javaboon (5. April 2010)

bei screenconsumer ist es die zeile:

    public static void main(String[] args) {

ebenso bei screenprovider


----------



## javaboon (5. April 2010)

wer weiß rat?


----------



## Matthias Reitinger (5. April 2010)

Hallo,

hast du mein Beispiel mal ausprobiert? Bei mir klappt das zumindest wunderbar…

Grüße,
Matthias


----------



## javaboon (6. April 2010)

danke matthias deins hat funktioniert 
aber warum nur in png und nicht in jpg?
habs umgeschrieben und gieng nicht 
und wie ist der datenverlust von 896 auf 847 kb zu erklären? ;D


----------



## javaboon (6. April 2010)

wie siehts aus?


----------



## Matthias Reitinger (6. April 2010)

javaboon hat gesagt.:


> wie siehts aus?


Threadpushing ist hier unerwünscht, ebenso wie durchgehende Kleinschreibung. Halte dich doch bitte an die Netiquette, der du mit der Anmeldung auf tutorials.de zugestimmt hast. Danke.



javaboon hat gesagt.:


> danke matthias deins hat funktioniert
> aber warum nur in png und nicht in jpg?
> habs umgeschrieben und gieng nicht
> und wie ist der datenverlust von 896 auf 847 kb zu erklären? ;D


Könntest du etwas präziser erläutern, was genau du umgeschrieben hast und was dann nicht ging? Und von welchem Datenverlust sprichst du?

Grüße,
Matthias


----------



## javaboon (6. April 2010)

Dann werd ich jetzt versuchen, der deutschen Grammatik treu zu bleiben. 
Es handelt sich nicht um ein Problem, ich frage mich lediglich woran es liegen könnte. Ich habe das Bild mit deinem Code in ein BufferedImage geschrieben, an localhost gesendet und wieder als Bilddatei abgespeichert. Nur unterscheiden sich diese zwei Bilder nun in ihrer Größe. Das "Ausgangsbild" ist 896kb groß und das versendete, und neu geschriebene Bild nurnoch 847kb. 
Auch habe ich versucht, ein Bild im jpg Format zu versenden. Ich habe einfach jedes png (aus deinem Code und die Dateien natürlich) durch jpg ersetzt, das funktionierte jedoch nicht  Nun frage ich mich (euch) warum.
Herzlichen Dank


----------



## javaboon (13. April 2010)

Ich weiß, dass Threathpushing unerwünscht ist, aber ich kenne mich nicht sehr mit Java aus und würde doch gerne erfahren wie diese Abweichung der Dateigröße zustande kommt und warum es nicht geklappt hat, dass ich im Quellcode alle "png" mithilfe von suchen und ersetzen durch "jpg" ersetzt habe. Ich hoffen dass mir das einer von euch erklären kann  Ich steh schon seit ner Woche ohne Antwort dar  
Ich bitte und danke euch um/für jede Hilfe.
Julian


----------



## d4rkY89 (17. April 2010)

Der Datenverlust kommt dadurch zustande, dass ImageIO beim Lesen des Bildes ein BufferedImage erstellt. Beim Schreiben rechnet/komprimiert ImageIO dieses BufferedImage wieder in das angegebene Format um, erzeugt also ein komplett neues Bild. Das hat nichts mehr mit der Originaldatei zu tun.

Wenn du einfach nur das Originalbild schicken willst, wieso dann dieser riesen Aufwand das Bild zig mal umzuwandeln? Les doch einfach direkt die Datei aus und verschicke die gelesenen Bytes.

*Server 1:*


```
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;


public class Server {
	public static void main(String[] args) {
		try {
			ServerSocket server = new ServerSocket(1234);
			
			Socket client = server.accept();
			sendFile(client, new File("C:/test.jpg"));  //Es kann jede beliebige Datei verwendet werden
			
			client.close();
			server.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private static void sendFile(Socket s, File f) throws IOException {
		if(f.isDirectory())
			throw new IllegalArgumentException("File cannot be a directory.");
		OutputStream out = s.getOutputStream();
		FileInputStream in = new FileInputStream(f);
		
		byte[] buffer = new byte[512];
		
		for(int i; (i = in.read(buffer)) != -1; ) {
			out.write(buffer, 0, i);
			out.flush();
		}
		
		in.close();
		out.close();
	}
}
```

*Client 1:*


```
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;


public class Client {
	public static void main(String[] args) {
		try {
			Socket serverConnection = new Socket(InetAddress.getLocalHost(), 1234);
			
			receiveFile(serverConnection, new File("received.jpg"));
			
			serverConnection.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private static void receiveFile(Socket s, File file) throws IOException {
		InputStream in = s.getInputStream();
		FileOutputStream out = new FileOutputStream(file);
		
		byte[] buffer = new byte[512];
		
		for(int i; (i = in.read(buffer)) != -1; ) {
			out.write(buffer, 0, i);
			out.flush();
		}
		
		in.close();
		out.close();		
	}
}
```

Ein BufferedImage selbst lässt sich meines Wissens nach nicht über ein OutputStream versenden. Allerdings kannst du folgendes Programm nutzen um selbst unkomprimierte Bilder (bmp) z.B. über das Internet zu versenden, da es das Bild vor dem Senden in ein beliebiges Format umwandelt.

*Server 2:*

```
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import javax.imageio.ImageIO;


public class Server {
	public static void main(String[] args) {
		try {
			ServerSocket server = new ServerSocket(1234);
			
			Socket client = server.accept();
			sendPicture(client, new File("D:/test.jpg"), true);
			
			client.close();
			server.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private static void sendPicture(Socket socket, File f, boolean original) throws IOException {
		if(f.isDirectory())
			throw new IllegalArgumentException("File cannot be a directory.");
		
		if(original) {
			OutputStream out = socket.getOutputStream();
	        FileInputStream in = new FileInputStream(f);
	       
	        byte[] buffer = new byte[512];
	       
	        for(int i; (i = in.read(buffer)) != -1; ) {
	            out.write(buffer, 0, i);
	            out.flush();
	        }
	       
	        in.close();
	        out.close();
		} else {
			BufferedImage img = ImageIO.read(f);
			ImageIO.write(img, "jpg", socket.getOutputStream());
			//Das Bildformat kannst du hier beispielsweise in ein komprimiertes Format (jpg, png, ect.)
			//ändern um weniger Daten über das Netzwerk oder Internet versenden zu müssen.
			//Das Format in welches das Bild am Ende gespeichert wird kannst du Anhand der Dateiendung
			//in der Client-Klasse ändern.
			//Achtung: Dieser Programmteil wird nur ausgeführt, wenn "original == false"!
		}
	}
}
```

*Client 2:*


```
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.imageio.ImageIO;

public class Client {
	public static void main(String[] args) {
		try {
			Socket serverConnection = new Socket(InetAddress.getLocalHost(), 1234);

			receivePicture(serverConnection, new File("D:/received.bmp"));

			serverConnection.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private static void receivePicture(Socket socket, File file) throws IOException {
		BufferedImage img = ImageIO.read(socket.getInputStream());
		//Das Speicherformat wird anhand der Dateiendung ausgelesen: "file.getName().substring(file.getName().lastIndexOf('.') + 1)"
		ImageIO.write(img, file.getName().substring(file.getName().lastIndexOf('.') + 1), file);
	}
}
```


----------

