Tuesday, 15 June 2010

Sending a screenshot (bufferedImage) over a socket in java -



Sending a screenshot (bufferedImage) over a socket in java -

i sending bufferedimage on socket , using illustration found in this post:

sender

bufferedimage image = ....; imageio.write(image, "png", socket.getoutputstream());

receiver

bufferedimage image = imageio.read(socket.getinputstream());

it works - if, , if, close sender's outputstream after line:

imageio.write(image, "png", socket.getoutputstream());

is there can apart closing outputstream?

also, there else can avoid using imageio altogether? seems take ages anything. note reading or writing hard disk in anyway should avoided @ costs due performance issues. need create transfer fast possible, (i'm experimenting , trying create client similar vnc , saving each screenshot hard disk slow downwards everything)..

@jon skeet

edit 3:

sender: (note sending jpg image not png).

int filesize; outputstream out = c.getclientsocket().getoutputstream(); bytearrayoutputstream bscrn = new bytearrayoutputstream(); imageio.write(screenshot, "jpg", bscrn); byte[] imgbyte = bscrn.tobytearray(); bscrn.flush(); bscrn.close(); filesize = bscrn.size(); out.write(new string("#fs " + filesize).getbytes()); //send filesize out.write(new string("#<im> \n").getbytes()); //notify start of image out.write(imgbyte); //write file system.out.println("finished");

reciever: (where input socket input stream)

attempt #1:

string str = input.tostring(); imagebytes = str.getbytes(); inputstream in = new bytearrayinputstream(imagebytes); bufferedimage image = imageio.read(in); in.close(); system.out.println("width=" + image.getwidth());

(failed: nullpointer exception on getwidth() line) understand error mean "corrupt image" because couldn't initialize it. correct?

attempt #2:

byte[] imagebytes = new byte[filesize]; (int j = 0; < filesize; i++) { imagebytes[j] = (byte) input.read(); } inputstream in = new bytearrayinputstream(imagebytes); bufferedimage image = imageio.read(in); in.close(); system.out.println("width=" + image.getwidth());

(failed: nullpointer exception on getwidth() line)

attempt #3:

if (filesize > 0) { int writtenbytes = 0; int buffersize = client.getreceivebuffersize(); imagebytes = new byte[filesize]; //create byte array big image byte[] buffer = new byte[buffersize];//create buffer { writtenbytes += input.read(buffer); //fill buffer system.out.println(writtenbytes + "/" + filesize); //show progress //copy buffer byte array contain total image system.arraycopy(buffer, 0, imagebytes, writtenbytes, client.getreceivebuffersize()); writtenbytes+=buffersize; } while ((writtenbytes + buffersize) < filesize); // read remaining bytes system.arraycopy(buffer, 0, imagebytes, writtenbytes-1, filesize-writtenbytes); writtenbytes += filesize-writtenbytes; system.out.println("finished reading! total read: " + writtenbytes + "/" + filesize); } inputstream in = new bytearrayinputstream(imagebytes); bufferedimage image = imageio.read(in); in.close();

(failed: reciever gives: null pointer exception)

attempt 4:

int readbytes = 0; imagebytes = new byte[filesize]; //create byte array big image while (readbytes < filesize) { readbytes += input.read(imagebytes); } inputstream in = new bytearrayinputstream(imagebytes); bufferedimage image = imageio.read(in); in.close(); system.out.println("width=" + image.getwidth());

(failed: sender gives: java.net.socketexception: connection reset peer: socket write error)

attempt #5:

using jon skeet's code snippet, image arrives, partially. saved file (1.jpg) see going on, , sends 80% of image, while rest of file filled blank spaces. results in partially corrupt image. here code tried: (note captureimg() not @ fault, saving file straight works)

sender:

socket s = new socket("127.0.0.1", 1290); outputstream out = s.getoutputstream(); bytearrayoutputstream bscrn = new bytearrayoutputstream(); imageio.write(captureimg(), "jpg", bscrn); byte imgbytes[] = bscrn.tobytearray(); bscrn.close(); out.write((integer.tostring(imgbytes.length)).getbytes()); out.write(imgbytes,0,imgbytes.length);

reciever:

inputstream in = clientsocket.getinputstream(); long starttime = system.currenttimemillis(); byte[] b = new byte[30]; int len = in.read(b); int filesize = integer.parseint(new string(b).substring(0, len)); if (filesize > 0) { byte[] imgbytes = readexactly(in, filesize); fileoutputstream f = new fileoutputstream("c:\\users\\dan\\desktop\\pic\\1.jpg"); f.write(imgbytes); f.close(); system.out.println("done");

the sender still gives connection reset peer: socket write error. click here total sized image

one alternative write image bytearrayoutputstream can determine length, write length output stream first.

then on receiving end, can read length, read many bytes byte array, create bytearrayinputstream wrap array , pass that imageio.read().

i'm not exclusively surprised doesn't work until output socket closed - after all, file contains valid png file and else isn't valid png file in itself, it? reader needs read end of stream before can finish - , "end" of network stream comes when connection closed.

edit: here's method read given number of bytes new byte array. it's handy have separate "utility" method.

public static byte[] readexactly(inputstream input, int size) throws ioexception { byte[] info = new byte[size]; int index = 0; while (index < size) { int bytesread = input.read(data, index, size - index); if (bytesread < 0) { throw new ioexception("insufficient info in stream"); } index += size; } homecoming data; }

java sockets bufferedimage

No comments:

Post a Comment