Click here to Skip to main content
15,888,263 members
Articles / Multimedia / GDI+
Tip/Trick

Save/Load Image between buffer

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
4 Mar 2014CPOL 16.4K   9   1
Save/Load Image between buffer

Given below is a small piece of code to save/load image between buffer:

C++
typedef std::vector<BYTE> vecByte;

bool save_img(const CImage &image, vecByte &buf) 
{
    IStream *stream = NULL;
    HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &stream);
    if( !SUCCEEDED(hr) )
        return false;
    image.Save(stream, Gdiplus::ImageFormatBMP);
    ULARGE_INTEGER liSize;
    IStream_Size(stream, &liSize);
    DWORD len = liSize.LowPart;
    IStream_Reset(stream);
    buf.resize(len);
    IStream_Read(stream, &buf[0], len);
    stream->Release();
    return true;
}

bool load_img(const vecByte &buf, CImage &image)
{
    UINT len = buf.size();
    HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, len);
    BYTE *pmem = (BYTE*)GlobalLock(hMem);
    memcpy(pmem, &buf[0], len);
    IStream    *stream = NULL;
    CreateStreamOnHGlobal(hMem, FALSE, &stream);
    image.Load(stream);
    stream->Release();
    GlobalUnlock(hMem);
    GlobalFree(hMem);
    return true;
}  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
SuggestionI think it's cool just error treatments. Pin
rfl.souza9-Jun-21 11:01
rfl.souza9-Jun-21 11:01 
thank you very much for the example, it helped here, i just did the error handling.

C++
auto image2Memory = [](const CImage& image, vecByte& buf, GUID fileType = Gdiplus::ImageFormatPNG)
		{
			bool ret(false);
			DWORD len = 0;
			IStream* stream = NULL;

			HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &stream);
			if (!SUCCEEDED(hr))
				return ret;

			hr = image.Save(stream, fileType);
			if (!SUCCEEDED(hr))
				goto Finished;

			ULARGE_INTEGER liSize;
			hr = IStream_Size(stream, &liSize);
			if (!SUCCEEDED(hr))
				goto Finished;
			len = liSize.LowPart;

			hr = IStream_Reset(stream);
			if (!SUCCEEDED(hr))
				goto Finished;
			buf.resize(len);

			hr = IStream_Read(stream, &buf[0], len);
			if (!SUCCEEDED(hr))
				goto Finished;
			
			ret = true;	

		Finished:
			if (stream != NULL)
			{
				stream->Release();
				stream = NULL;
			}
			return ret;
		};

		auto memory2Image = [](const vecByte& buf, CImage& image)
		{
			bool ret(false);
			UINT len = buf.size();
			HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, len);
			IStream* stream = NULL;
			HRESULT hr = ERROR_SUCCESS;

			if (hMem == NULL)							
				return false;			

			BYTE* pmem = (BYTE*)GlobalLock(hMem);
			if (pmem == NULL)
				goto Finished;

			memcpy(pmem, &buf[0], len);
			
			hr = CreateStreamOnHGlobal(hMem, FALSE, &stream);
			if (FAILED(hr))			
				goto Finished;
			
			hr = image.Load(stream);
			if (FAILED(hr))
				goto Finished;

			ret = true;

		Finished:

			if (stream != NULL)
			{
				stream->Release();
				stream = NULL;
			}

			GlobalUnlock(hMem);
			GlobalFree(hMem);

			return ret;
		};

Rafael

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.