Send/Receive wxImage by using wxSocketBase Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
sago
Earned a small fee
Earned a small fee
Posts: 18
Joined: Tue Oct 21, 2008 7:59 am

Send/Receive wxImage by using wxSocketBase

Post by sago »

Hi,

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

Thx.
JimFairway
wxWorld Domination!
wxWorld Domination!
Posts: 1059
Joined: Sun Dec 30, 2007 6:40 pm
Location: Canada

Post 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
OS: Vista SP1, wxWidgets 2.8.7.
sago
Earned a small fee
Earned a small fee
Posts: 18
Joined: Tue Oct 21, 2008 7:59 am

Post 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?
JimFairway
wxWorld Domination!
wxWorld Domination!
Posts: 1059
Joined: Sun Dec 30, 2007 6:40 pm
Location: Canada

Post 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
OS: Vista SP1, wxWidgets 2.8.7.
sago
Earned a small fee
Earned a small fee
Posts: 18
Joined: Tue Oct 21, 2008 7:59 am

Post 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.
JimFairway
wxWorld Domination!
wxWorld Domination!
Posts: 1059
Joined: Sun Dec 30, 2007 6:40 pm
Location: Canada

Post 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
OS: Vista SP1, wxWidgets 2.8.7.
sago
Earned a small fee
Earned a small fee
Posts: 18
Joined: Tue Oct 21, 2008 7:59 am

Post by sago »

Thank you very much for these answers, I think that I have a good track.
Post Reply