65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 ADO 从数据库加载图像文件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (21投票s)

2006 年 1 月 28 日

CPOL

1分钟阅读

viewsIcon

133296

downloadIcon

3053

通过 ADO 将图像文件放入数据库并从中检索。

Sample Image - ADOImageDb.jpg

引言

将图像文件放入数据库并从中检索并非易事。 如果您想在互联网上查找此类示例,您会惊讶地发现没有 C++ 示例。 只有信息表明您必须使用 SafearraySetChunkGetChunk 方法。

本文将展示如何通过 ADO 将图像文件放入数据库,以及如何检索它们。 通过此示例,您可以使用任何文件格式,例如 Word、Excel 等,而不仅仅是图像文件格式。

实现

该示例包含两种将图像文件放入数据库并从中检索的方法。 第一种方法从数据库检索数据,在临时目录中创建一个文件,并将数据放入创建的文件中。 参数 strImageName 是将创建的文件名。 第二个参数指示包含图像数据的 ADO 字段对象。

以下代码示例显示了实现

CString CADOImageDBDlg::GetImageFromADO(CString 
                  strImageName, FieldPtr pField)
{
    //Creating temp file
    char tmpPath[_MAX_PATH+1];
    GetTempPath(_MAX_PATH,tmpPath);
    strImageName.Insert(0,tmpPath);
    CFile outFile(strImageName, 
      CFile::modeCreate|CFile::modeWrite);
 
    //Helper variable for retrieving image data
    unsigned char* lpData = NULL;
    long lngOffSet = 0;
    long lngSize=pField->ActualSize;
    const long ChunkSize=50;     
    _variant_t varChunk;    
    UCHAR chData;
    HRESULT hr;
    long lBytesCopied = 0;
    lpData=new unsigned char [lngSize];
 
    //Retrieveing data from vararray
    while(lngOffSet < lngSize)
    { 
        try
        {
            //Get 50 size long chunk from database
            varChunk = pField->GetChunk(ChunkSize);
     
            //putting chunk in to safe array
            for(long lIndex = 0; lIndex <= 
                    (ChunkSize - 1); lIndex++)
            {
                hr= 
                  SafeArrayGetElement(varChunk.parray, 
                  &lIndex, &chData);
                if(SUCCEEDED(hr))
                {
                    ((UCHAR*)lpData)[lBytesCopied] = chData;
                    lBytesCopied++;
                }
                else
                    break;
            }
            lngOffSet += ChunkSize;
        }
        catch(_com_error &e)
        {
            dump_com_error(e);
            return FALSE;
        }
    }
 
    //
    LPSTR buffer = (LPSTR)GlobalLock(lpData);
    // write data in to file
    outFile.Write(lpData,lngSize);
    
    // free reserved data
    GlobalUnlock(lpData);
    delete lpData;
     
    //Return full path file
    return strImageName;
}
 
bool CADOImageDBDlg::PutImageInADO(CString 
           strFilePath,FieldPtr pFileData)
{
    //Opent File
    CFile fileImage;
    CFileStatus fileStatus;
    fileImage.Open(strFilePath, CFile::modeRead);
    fileImage.GetStatus(fileStatus);

    //Alocating memory for data 
    ULONG nBytes = (ULONG)fileStatus.m_size;
    HGLOBAL hGlobal = GlobalAlloc(GPTR,nBytes);
    LPVOID lpData = GlobalLock(hGlobal);

    //Putting data in to file
    fileImage.Read(lpData,nBytes);
 
 
    HRESULT hr;
    _variant_t varChunk;
    long lngOffset = 0;
    UCHAR chData;
    SAFEARRAY FAR *psa = NULL;
    SAFEARRAYBOUND rgsabound[1];
 
    try
    {
        //Create a safe array to 
        //store the array of BYTES 
        rgsabound[0].lLbound = 0;
        rgsabound[0].cElements = nBytes;
        psa = SafeArrayCreate(VT_UI1,1,rgsabound);
         
        while(lngOffset < (long)nBytes)
        {
            chData      = ((UCHAR*)lpData)[lngOffset];
            hr = SafeArrayPutElement(psa, 
                       &lngOffset, &chData);
             
            if(hr!=S_OK) 
            return false;
             
            lngOffset++;
        }
        lngOffset = 0;
 
        //Assign the Safe array  to a variant. 
        varChunk.vt = VT_ARRAY|VT_UI1;
        varChunk.parray = psa;
         
        hr = pFileData->AppendChunk(varChunk);
 
        if(hr!=S_OK) 
            return false;
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;
    }

    //Free memory
    GlobalUnlock(lpData);
    return true;
}

为了图像显示,我创建了一个包装 freeimage 库的类。

更新历史

  • 1.0.0.119 - 2006 年 1 月 27 日 - 第一个发布版本。
© . All rights reserved.