Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Loading image files from a database, using ADO

0.00/5 (No votes)
27 Jan 2006 1  
Putting and retrieving images files to and from a database, via ADO.

Sample Image - ADOImageDb.jpg

Introduction

Putting and retrieving image files in to a database, is not a simple task. I you want to look on the Internet for such a sample, you will be surprised that there is no C++ sample for that. There is only information, that you have to use the Safearray, SetChunk, and GetChunk methods.

This article will show how you can put image files in to a database via ADO, as well as how you can retrieve them. With this example, you can use any file format such as Word, Excel etc., not just image file formats.

Implementation

The example contains two methods for putting and retrieving image files to and from a database. The first method retrieves data from the database, create a file in a temporary directory, and puts the data into a file created. The parameter strImageName is the name of the file that will be created. The second parameter indicates the ADO field object containing the image data.

The following code sample shows the implementation:

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;
}

For image display, I created a class which wraps the freeimage library.

Update history

  • 1.0.0.119 - January 27, 2006 - First release version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here