Gdiplus::Image 可輕鬆顯示 JPEG/GIF/PNG,但缺乏原生序列化支援。若需將圖片內容儲存至應用程式文檔(CArchive),必須自行實作序列化/反序列化邏輯。
流程:
HGLOBAL 可移動記憶體CreateStreamOnHGlobal 包裝成 IStreamImage::Save(stream, CLSID_encoder) 以 BMP 格式寫入串流HGLOBAL → IStream → Image::FromStreamSerialize 實作void CDoc::Serialize(CArchive& ar) {
if (ar.IsStoring()) {
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, 0);
IStream* pStm = NULL;
CreateStreamOnHGlobal(hMem, TRUE, &pStm);
CLSID clsid; GetCodecClsid(L"image/bmp", &clsid); // BMP 編碼器
m_pImage->Save(pStm, &clsid, NULL);
LARGE_INTEGER li = {0}; pStm->Seek(li, STREAM_SEEK_SET, NULL);
DWORD len = GlobalSize(hMem);
BYTE* pData = (BYTE*)GlobalLock(hMem);
ar << len; ar.Write(pData, len);
pStm->Release(); GlobalUnlock(hMem);
} else {
DWORD len; ar >> len;
HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, len);
IStream* pStm = NULL;
CreateStreamOnHGlobal(hMem, FALSE, &pStm);
BYTE* pData = (BYTE*)GlobalLock(hMem);
ar.Read(pData, len);
if (m_pImage) { delete m_pImage; m_pImage = NULL; }
m_pImage = Image::FromStream(pStm, FALSE);
pStm->Release(); GlobalUnlock(hMem);
// 注意:此處不可 GlobalFree(hMem),否則圖片無法顯示
}
}
GetCodecClsidint GetCodecClsid(const WCHAR* mime, CLSID* pClsid) {
UINT n=0, sz=0; GetImageEncodersSize(&n, &sz);
ImageCodecInfo* pInfo = (ImageCodecInfo*)malloc(sz);
GetImageEncoders(n, sz, pInfo);
for (UINT i=0; i
支援 MIME:image/bmp、image/jpeg、image/gif、image/png、image/tiff。
HGLOBAL,Image 內部仍引用該記憶體gdiplus.lib 並初始化 GdiplusStartup