/*参数说明*/
char * m_pJPGBuffer;  //用于图片缓冲存储
IStream * pStream;           //图片信息流,用于将图片载用内存
IPicture * pPicture;         //保存图片信息
DWORD m_nFileLen;    //图片文件长度
/*以下函数实现从磁盘读入图片*/
/* const char *pPathname 该参数是读取图片的路径*/
BOOL CEditPicture::LoadJPGFile(const char *pPathname)
{
CFile file;
if( !file.Open( pPathname, CFile::modeRead) )  //打开文件
return FALSE;
m_nFileLen = file.GetLength();  //获取图片长度
HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE, m_nFileLen ); //开辟空间
    LPVOID lpBuf = ::GlobalLock( hMem );
if( file.ReadHuge( lpBuf, m_nFileLen ) != m_nFileLen ) //开辟空间失败
return FALSE;
file.Close(); //关闭文件
m_pJPGBuffer = (char *)lpBuf;
::GlobalUnlock( hMem );
if ( CreateStreamOnHGlobal( hMem, TRUE, &pStream ) !=S_OK ) 
return FALSE;
if ( OleLoadPicture( pStream, m_nFileLen, TRUE, IID_IPicture, ( LPVOID * )&pPicture ) !=S_OK )  //载入图片失败
return FALSE;
return TRUE;
}
/*以下函数实现将图片格式文件转为二进制格式文件*/
void CEditPicture::SetPictureToVariant(VARIANT &pvList, unsigned char *sPicture)
{
   SAFEARRAYBOUND saBound[1];
saBound[0].cElements = m_nFileLen;
saBound[0].lLbound = 0;
SAFEARRAY *pSA = SafeArrayCreate(VT_UI1, 1, saBound);
for (long l = 0; l < (long)m_nFileLen; l ++)
{
SafeArrayPutElement( pSA, &l, (void*)&sPicture[l]);
}
VariantClear(&pvList);
pvList.vt = VT_UI1 | VT_ARRAY;
pvList.parray = pSA;
}
/*以下代码实现将二进制格式文件转化为图片格式文件*/
void CEditPicture::SetVariantToPicture(char *pBuf, _variant_t &varBLOB, long lDataSize)
{
m_nFileLen = (DWORD)lDataSize;
try
{
if(varBLOB.vt == (VT_ARRAY | VT_UI1))
{
if(m_pJPGBuffer = new char[lDataSize+1])
{
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
memcpy(m_pJPGBuffer,pBuf,lDataSize);
SafeArrayUnaccessData (varBLOB.parray);
m_nFileLen = lDataSize;
HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE, m_nFileLen );
LPVOID lpBuf = ::GlobalLock( hMem );
memcpy(lpBuf,m_pJPGBuffer,m_nFileLen);  //开辟空间存放
::GlobalUnlock( hMem );
if ( CreateStreamOnHGlobal( hMem, TRUE, &pStream ) !=S_OK )
return ;
if ( OleLoadPicture( pStream, m_nFileLen, TRUE, IID_IPicture, ( LPVOID * )&pPicture ) !=S_OK )
return ;     
}
}
}
catch(...)
{
AfxMessageBox("从数据库中读取图像有错!");
return;
}
}
/*以下代码将图片显示在界面上*/
void CEditPicture::DrawImage(int x, int y, CDC *pDC)
{
if (pPicture != NULL) 
{
long nWidth,nHeight;  
pPicture->get_Width( &nWidth );   
pPicture->get_Height( &nHeight ); 

CSize sz( nWidth, nHeight );
pPicture->Render(pDC->m_hDC,x,y,120,120,0,nHeight,nWidth,-nHeight,NULL);    
/*(x,y)图像左上角的坐标,图像显示大小为120*120,图像放大缩小指需要修改该参数即可实现*/
}
}越详细越好!!!多谢各位了!!!

解决方案 »

  1.   


    BOOL CEditPicture::LoadJPGFile(const char *pPathname) 

    CFile file; 
    if( !file.Open( pPathname, CFile::modeRead) )  //打开图片文件 
    return FALSE; 
    m_nFileLen = file.GetLength();  //获取图片文件长度 
    HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE, m_nFileLen ); //申请一个全局内存句柄用来保存图片数据 
        LPVOID lpBuf = ::GlobalLock( hMem ); // 获取内存句柄表示的内存指针
    if( file.ReadHuge( lpBuf, m_nFileLen ) != m_nFileLen ) // 把文件内容读入内存中
      return FALSE; 
    file.Close(); //关闭文件 
    m_pJPGBuffer = (char *)lpBuf; // 以字节方式来访问内存
    ::GlobalUnlock( hMem ); // 不再使用内存指针(这里会有问题,上一句保存的m_pJPGBuffer将无效,应该注释掉上一句)
    if ( CreateStreamOnHGlobal( hMem, TRUE, &pStream ) !=S_OK )  // 从内存句柄创建一个IStream对象
    return FALSE; 
    if ( OleLoadPicture( pStream, m_nFileLen, TRUE, IID_IPicture, ( LPVOID * )&pPicture ) !=S_OK )  // 从IStream数据中构造一个IPicture对象
    return FALSE; 
    return TRUE; 

    /*以下函数实现将图片格式文件转为二进制格式文件*/ 
    void CEditPicture::SetPictureToVariant(VARIANT &pvList, unsigned char *sPicture) 

       SAFEARRAYBOUND saBound[1]; 
    saBound[0].cElements = m_nFileLen; 
    saBound[0].lLbound = 0; 
    SAFEARRAY *pSA = SafeArrayCreate(VT_UI1, 1, saBound); // 创建一个一维的字节数组,数组长度是图片数据的字节数。在VARIANT中使用数组必须使用SAFEARRAY
    for (long l = 0; l  < (long)m_nFileLen; l ++) // 通过循环把图片数据复制到数组中

    SafeArrayPutElement( pSA, &l, (void*)&sPicture[l]); 

    VariantClear(&pvList); // 清理VARIANT的已有内容
    pvList.vt = VT_UI1  ¦ VT_ARRAY; 
    pvList.parray = pSA; // 设置VARIANT为SAFEARRAY

    /*以下代码实现将二进制格式文件转化为图片格式文件*/ 
    void CEditPicture::SetVariantToPicture(char *pBuf, _variant_t &varBLOB, long lDataSize) 

    m_nFileLen = (DWORD)lDataSize; 
    try 

    if(varBLOB.vt == (VT_ARRAY  ¦ VT_UI1)) // 判断VARIANT的类型是否是字节数组

    if(m_pJPGBuffer = new char[lDataSize+1]) // 分配缓冲区内存

    SafeArrayAccessData(varBLOB.parray,(void **)&pBuf); // 准备访问数组数据
    memcpy(m_pJPGBuffer,pBuf,lDataSize); // 把数组中的数据复制到缓冲区内存中
    SafeArrayUnaccessData (varBLOB.parray); // 不再访问数组数据
    m_nFileLen = lDataSize; 
    HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE, m_nFileLen ); // 分配全局内存句柄
    LPVOID lpBuf = ::GlobalLock( hMem ); // 获取内存句柄的内存指针
    memcpy(lpBuf,m_pJPGBuffer,m_nFileLen);  // 把缓冲区中的数据复制到内存句柄指示的内存块中
    ::GlobalUnlock( hMem ); // 不再使用内存句柄的内存指针
    if ( CreateStreamOnHGlobal( hMem, TRUE, &pStream ) !=S_OK ) // 从内存句柄获得IStream对象
    return ; 
    if ( OleLoadPicture( pStream, m_nFileLen, TRUE, IID_IPicture, ( LPVOID * )&pPicture ) !=S_OK ) // 从IStream对象获得IPicture接口
    return ;      



    catch(...) 

    AfxMessageBox("从数据库中读取图像有错!"); 
    return; 


    /*以下代码将图片显示在界面上*/ 
    void CEditPicture::DrawImage(int x, int y, CDC *pDC) 

    if (pPicture != NULL)  

    long nWidth,nHeight;   
    pPicture->get_Width( &nWidth );    // 读取图片的像素宽度
    pPicture->get_Height( &nHeight );  // 读取图片像素高度CSize sz( nWidth, nHeight ); 
    pPicture->Render(pDC->m_hDC,x,y,120,120,0,nHeight,nWidth,-nHeight,NULL);     // 把图片直接绘制到pDC中
    /*(x,y)图像左上角的坐标,图像显示大小为120*120,图像放大缩小指需要修改该参数即可实现*/ 

      

  2.   

    楼主不妨用GDI+试试先把文件读到流里面,然后用Image::FromStream 方法获得Image对象,然后用Graphics::DrawImage 画就可以了