Page 1 of 1

Send/Receive wxImage by using wxSocketBase

Posted: Thu Dec 04, 2008 11:28 am
by sago
Hi,

Is it possible to send and receive wxImage by using wxSocketBase::Write and wxSocketBase::Read functions?

Thx.

Posted: Thu Dec 04, 2008 1:12 pm
by JimFairway
Hi,

If you're only interested in sending a single file, then the code snippet at the top of this thread:http://forums.wxwidgets.org/viewtopic.php?t=21694 should do the trick for you.

If you are sending multiple images, you would need some kind of mechanism of telling the other side the size of the file.

You could then use wxSocketBase::Read for the specified number of bytes into memory, then you could convert that to a wxMemoryInputStream and use wxImage::LoadFile.
Code could look like this (not compiled not tested):

Code: Select all

unsigned char len[4];
size_t size;
unsigned char *memp;

mySock->Read(&len,4);  // read the length
size = (len[0] << 24) + (len <[1] << 16) + (len[2] << 8) + len[3];  // presumes msb was sent first...
memp = malloc(size);   // get enough memory
mySock->Read(memp,size);

wxMemoryInputStream inStream(memp,size);
wxImage.LoadFile(inStream,wxBITMAP_TYPE_JPEG);

free(memp); // delete the buffer..
Hope that helps,

Jim

Posted: Thu Dec 04, 2008 1:54 pm
by sago
Thanks for your answer.


This code:

Code: Select all

unsigned char *memp;
mySock->Read(memp,size);
means that I must send an unsigned char pointer like:

Code: Select all

unsigned char *memp;
...
mySock->Write(memp,size);
So if I have a wxImage, how can I transform it into unsigned char* ;
Or if I have a wxInputStream* , how can I tranform it into unsigned char* in order to send it with the function Write of wxSocket and how can I find the size of the buffer to send?

Posted: Thu Dec 04, 2008 2:49 pm
by JimFairway
Hi,

If you haven't read the file into a wxImage yet, you can use wxFile to get at the size and the data in the file itself.
If you have read it, best to save it to
So the sender could look something like (again, not compiled nor tested):

Code: Select all

wxFile myFile(wxT("path_to_my_image")); // or where ever the file is
unsigned char len[4];   // buffer to store the size of the image
size_t size = myFile.Length(); // the size of the file
len[0] = (size >> 24) & 255;   // convert to bytes... (MSB first)
len[1] = (size >> 16) & 255;
len[2] = (size >> 8) & 255;
len[3] = size & 255;

mySock->Write(len, 4);  // send the size

// now send the data
unsigned char *data = (unsigned char *) malloc(size);
myFile.Read(data, size);
mySock->Write(data,size);

Hope that works!

If you change the receiver use the wxFile to store all the data to a file (instead of image load), you can send any file type you want to the other side.
Of course, you would have to add a step at the beginning to provide a filename or something.

Jim

Posted: Thu Dec 04, 2008 3:38 pm
by sago
In fact, I get the image from an IP camera:

Code: Select all

wxString httpAddress= "http://...";
wxURL imageURL(httpAddress);
wxInputStream *inputStream = imageURL.GetInputStream();
wxImage downloadedImage;
if ((inputStream != NULL) && (downloadedImage.LoadFile(*inputStream, wxBITMAP_TYPE_JPEG)))
{
  downloadedImage.SaveFile("image.jpg", wxBITMAP_TYPE_JPEG);
}
So at this moment I write the image grabbed from the camera.
But now I want to avoid write it on the disk. I want to send it to a client by sockets.
But I don't know how to get the size of the buffer image and tranform it into unsigned char*

I think it is possible to find the size of the buffer in the http response header.

Posted: Thu Dec 04, 2008 3:57 pm
by JimFairway
Hi,

Use wxMemoryOutputStream to write the JPEG file to memory.
You would need to do that, as it's only when you save the file that wxImage converts it to JPEG format - before that it's kept pixel by pixel in RGB format.

Code: Select all

 {
  wxMemoryOutputStream memStream(NULL);
  downloadedImage.SaveFile(memStream, wxBITMAP_TYPE_JPEG);
  size_t size = memStream.GetSize(); // the size of the file
  wxStreamBuffer *myBuf = memStream.GetOutputStreamBuffer();
// then use read to get the data...
  myBuf.Read(...);
// or directly
   memStream.CopyTo(...);
 } 
You should also be aware that as you are decompressing/compressing the JPEG file, there is no guarantee that the final file will the exactly the same quality as the original that was on the server.

Jim

Posted: Thu Dec 04, 2008 4:31 pm
by sago
Thank you very much for these answers, I think that I have a good track.