wxImage to buffer and back 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
User avatar
papillon68
Experienced Solver
Experienced Solver
Posts: 86
Joined: Tue Nov 06, 2007 11:19 pm

wxImage to buffer and back

Post by papillon68 » Thu Sep 27, 2018 6:25 pm

Hello, I have an issue trying to save data to buffer and read it back. I'll show what's going on.

In this first section, I basically load a bitmap file into a wxMemoryBuffer:

Code: Select all

	wxInitAllImageHandlers();
	wxImage image("resources/images/in.bmp", wxBITMAP_TYPE_BMP, -1);
	if (image.IsOk() == false)	return;
	unsigned int byteCount = image.GetWidth()*image.GetHeight() * 3;	
	wxMemoryBuffer bufferBLOB(byteCount);
	bufferBLOB.AppendData(image.GetData(), byteCount);
At this point, I want to read the data back, but the LoadFile command fails

Code: Select all

	wxMemoryInputStream stream(bufferBLOB.GetData(), bufferBLOB.GetDataLen());	// (also tried bufferBLOB.GetBufSize()
	wxImage theBitmap;
	if (!theBitmap.LoadFile(stream, wxBITMAP_TYPE_BMP)) MyApp::showMessage("can't load bmp", "s");
	theBitmap.SaveFile("resources/images/out.bmp", wxBITMAP_TYPE_BMP);
I'm not sure what could be wrong.
Windows 10, MS VC++ 2015 (vc140), WxWidgets 3.13

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2388
Joined: Sun Jan 03, 2010 5:45 pm

Re: wxImage to buffer and back

Post by PB » Thu Sep 27, 2018 6:33 pm

For starters: I would assume that the image data (i.e., an array or RGB values) is not a format that wxImage::LoadFile(x, wxBITMAP_TYPE_BMP) expects. If you write wxImage data, you need to read them as such.

TBH, I am not exactly sure what you want to achieve with your code...

Edit
This works

Code: Select all

bool wxImageToImage(const wxImage& source, wxImage& dest)
{
    wxCHECK(source.IsOk(), false);    

    const wxBitmapType bitmapType = wxBITMAP_TYPE_BMP;    
    wxMemoryOutputStream streamOut;
    
    if ( !source.SaveFile(streamOut, bitmapType) )
        return false;

    wxMemoryInputStream streamIn(streamOut);
    
    return dest.LoadFile(streamIn, bitmapType);
}
However, using wxMemoryBuffer for wxImage::SetData() did not work for me (regardless of the value of static_data). The docs states that the pointer for SetData() cannot be created by new, only by malloc(), so perhaps this is the reason?

User avatar
papillon68
Experienced Solver
Experienced Solver
Posts: 86
Joined: Tue Nov 06, 2007 11:19 pm

Re: wxImage to buffer and back

Post by papillon68 » Thu Sep 27, 2018 8:17 pm

Basically I'm trying to validate the image data stored in the buffer, thus reading it back and saving it again to an image to compare with the initial one.
Windows 10, MS VC++ 2015 (vc140), WxWidgets 3.13

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2388
Joined: Sun Jan 03, 2010 5:45 pm

Re: wxImage to buffer and back

Post by PB » Thu Sep 27, 2018 8:21 pm

So you can do it as I showed in my previous post, right?

If you for some reason need to use wxMemoryBuffer, you can do it for example like this

Code: Select all

bool wxImageToMemoryBuffer(const wxImage& image, wxMemoryBuffer& buffer)
{
    wxCHECK(image.IsOk(), false); 
    
    wxMemoryOutputStream stream;
    
    if ( !image.SaveFile(stream, wxBITMAP_TYPE_BMP) )
        return false;
    
    buffer.SetBufSize(stream.GetSize());
    buffer.SetDataLen(stream.GetSize());
    stream.CopyTo(buffer.GetData(), buffer.GetDataLen());
    
    return true;
}

bool wxMemoryBufferToImage(const wxMemoryBuffer& buffer, wxImage& image)
{
    wxCHECK(!buffer.IsEmpty(), false); 

    wxMemoryInputStream stream(buffer.GetData(), buffer.GetDataLen());
    
    return image.LoadFile(stream);
}

bool wxImageToImage2(const wxImage& source, wxImage& dest)
{
    wxMemoryBuffer buffer;

    if ( wxImageToMemoryBuffer(source, buffer) )
        return wxMemoryBufferToImage(buffer, dest);

    return false;
}

User avatar
papillon68
Experienced Solver
Experienced Solver
Posts: 86
Joined: Tue Nov 06, 2007 11:19 pm

Re: wxImage to buffer and back

Post by papillon68 » Thu Sep 27, 2018 8:35 pm

Thank you very much PB, that works perfectly. I guess then the issue I had was not using malloc on the wxImage initialization. Will try that too...
Windows 10, MS VC++ 2015 (vc140), WxWidgets 3.13

PB
Part Of The Furniture
Part Of The Furniture
Posts: 2388
Joined: Sun Jan 03, 2010 5:45 pm

Re: wxImage to buffer and back

Post by PB » Thu Sep 27, 2018 8:53 pm

papillon68 wrote:Thank you very much PB, that works perfectly. I guess then the issue I had was not using malloc on the wxImage initialization
As I wrote in my first post, I believe that the main issue was that you wrote only the array of RGB triplets obtained by wxImage::GetData()
papillon68 wrote:

Code: Select all

	unsigned int byteCount = image.GetWidth()*image.GetHeight() * 3;	
	wxMemoryBuffer bufferBLOB(byteCount);
	bufferBLOB.AppendData(image.GetData(), byteCount);
but tried to read it as if the data were stored in the Windows Bitmap format
papillon68 wrote:

Code: Select all

	wxMemoryInputStream stream(bufferBLOB.GetData(), bufferBLOB.GetDataLen());	// (also tried bufferBLOB.GetBufSize()
	wxImage theBitmap;
	if (!theBitmap.LoadFile(stream, wxBITMAP_TYPE_BMP)) MyApp::showMessage("can't load bmp", "s");
Windows bitmap format obviously has to store much more information than just RGB triplets.


The notice about malloc regarded impossibility of using wxMemoryBuffer as the source for wxImage::SetData().

Post Reply