#keywords C++, Gdi+, Bitmap, Serialize {{{#!gcode int GetEncoderClsid(const TCHAR* format, CLSID* pClsid) { UINT num = 0; UINT size = 0; ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if (pImageCodecInfo == NULL) return -1; // Failure GetImageEncoders(num, size, pImageCodecInfo); for (UINT j = 0; j < num; ++j) { if (_tcscmp(pImageCodecInfo[j].MimeType, format) == 0) { *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; // Success } } free(pImageCodecInfo); return -1; // Failure } }}} {{{#!gcode // Serialize HRESULT hr = E_FAIL; HGLOBAL gGlobal = GlobalAlloc(GMEM_MOVEABLE, 0); IStream* stream = nullptr; hr = CreateStreamOnHGlobal(gGlobal, TRUE, &stream); ASSERT(SUCCEEDED(hr)); CLSID pngClsid; GetEncoderClsid(_T("image/png"), &pngClsid); hr = bitmap->Save(stream, &pngClsid, NULL); // bitmap <- Gdiplus::Bitmap ASSERT(SUCCEEDED(hr)); // 저장된 이미지를 위한 버퍼 할당 LARGE_INTEGER seekPos = { 0, }; ULARGE_INTEGER imageSize = { 0, }; hr = stream->Seek(seekPos, STREAM_SEEK_CUR, &imageSize); ASSERT(SUCCEEDED(hr)); BYTE* buffer = new BYTE[imageSize.LowPart]; // 스트림으로부터 버퍼 채움 hr = stream->Seek(seekPos, STREAM_SEEK_SET, 0); ASSERT(SUCCEEDED(hr)); hr = stream->Read(buffer, imageSize.LowPart, 0); ASSERT(SUCCEEDED(hr)); // buffer <- Serialized data // ... // Cleanup stream->Release(); delete[] buffer; }}} {{{#!gcode // Deserialize IStream* stream = SHCreateMemStream((BYTE*)buffer, bufferLen); Bitmap* bitmap = Gdiplus::Bitmap::FromStream(stream); stream->Release(); delete bitmap; }}} ---- {{{ }}}