Image类的序列化

 

 Image类的序列化

利用GDI+图形设备接口提供的Image类我们可以很方便地显示JPEG、GIF等文件格式的图片,
但美中不足的是Image类未提供序列化数据的功能,
如果要将从JPEG、GIF等格式的文件中读取的图片数据保存到我们自己开发的应用程序文档中,
并能从文档中读取已经保存的图片数据并正确的显示出来,就必须实现Image类数据的序列化。
假如在你的文档类中有个指向Image类的成员指针变量m_pImage用于显示图片,
那么在文档类的序列化函数Serialize(CArchive& ar)中加入以下的代码就能实现m_pImage所指向的图片数据的序列化:

if  (ar.IsStoring())
{
    HGLOBAL m_hMem 
= GlobalAlloc(GMEM_MOVEABLE, 0);
    IStream 
*pstm=NULL;
    CreateStreamOnHGlobal(m_hMem, TRUE, 
&pstm);
    CLSID clsid;
    USES_CONVERSION;
    GetCodecClsid(A2W(
"image/bmp"), &clsid);
    m_pImage
->Save(pstm,&clsid,NULL);
    
if (pstm==NULL)
        
return;
    LARGE_INTEGER liBeggining 
= 0 };
    pstm
->Seek(liBeggining, STREAM_SEEK_SET, NULL);
    DWORD wTemp
=GlobalSize(m_hMem);
    LPBYTE lpData 
= (LPBYTE)GlobalLock(m_hMem);
    ar 
<< wTemp; 
    ar.Write(lpData,wTemp);
    pstm
->Release();
    GlobalUnlock(m_hMem);
}

else
{
    DWORD wTemp;
    ar 
>> wTemp; 
    HGLOBAL m_hMem 
= GlobalAlloc(GMEM_FIXED, wTemp);
    
if (m_hMem == NULL)
        
return;
    IStream 
*pstm=NULL;
    CreateStreamOnHGlobal(m_hMem,FALSE,
&pstm);
    
if (pstm==NULL)
        
return;
    BYTE
* pmem = (BYTE*)GlobalLock(m_hMem);
    ar.Read(pmem,wTemp);
    
if (m_pImage) {
        delete m_pImage;
        m_pImage 
= NULL;
    }

    
using namespace Gdiplus; 
    m_pImage 
= Image::FromStream(pstm, FALSE);
    pstm
->Release();
    GlobalUnlock(m_hMem);
    
//注意此处不能加GlobalFree(m_hMem);否则图片显示不出来。
}

其中函数GetCodecClsid的实现代码如下:


int  GetCodecClsid( const  WCHAR *  format, CLSID *  pClsid)
    
{
        UINT num 
= 0// number of image encoders
        UINT size = 0// size of the image encoder array in bytes
        using namespace Gdiplus; 
        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( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
            
{
                
*pClsid = pImageCodecInfo[j].Clsid;
                
return j; // Success
            }
 
        }
 // for
        return -1// Failure
}
  //  GetCodecClsid

 形参format用以说明图片数据的保存格式,可以取以下一些值:
"image/bmp"(位图格式),"image/jpeg"(JPEG格式),"image/gif"(GIF格式)等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值