Click here to Skip to main content
Licence CPOL
First Posted 27 Jan 2006
Views 82,951
Bookmarked 87 times

Loading image files from a database, using ADO

By | 27 Jan 2006 | Article
Putting and retrieving images files to and from a database, via ADO.
 
Part of The SQL Zone sponsored by
See Also

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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Bahrudin Hrnjica

Software Developer

Bosnia And Herzegovina Bosnia And Herzegovina

Member

Senior Software Developer and Microsoft MVP 2011 for Visual C#.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generaladding camera capture to this program Pinmembersuyun9020:03 29 Jun '09  
GeneralRe: adding camera capture to this program PinmemberMember 26861431:33 22 Jan '10  
AnswerRe: adding camera capture to this program PinmemberRaviRanjankr0:09 1 Mar '11  
Questionwhy should we put images in db? Pinmemberikprog21:31 5 Feb '09  
Generalcomparing images in vb Pinmemberuet1:41 2 Mar '08  
AnswerRe: comparing images in vb PinmemberRaviRanjankr0:15 1 Mar '11  
GeneralNot compatible with Visual Studio 9 PinmemberPatrickquinn12122:28 19 Feb '08  
GeneralRe: Not compatible with Visual Studio 9 PinmemberBahrudin Hrnjica9:10 15 Aug '08  
Questionwhy i can't download this source? Pinmemberc_glacier16:35 28 Jan '08  
Generalnothing in Internet. strange PinmemberBalinTomsk10:23 18 Sep '07  
GeneralMySQL with TEXT type column PinmemberAlexEvans12:48 6 Jul '07  
QuestionHow to Remove Image while saving record Pinmembergargamehl14:44 17 Apr '07  
GeneralDatas saved as Long Binary data in Access file [modified] PinmemberPriyah0:03 8 Nov '06  
GeneralRe: Datas saved as Long Binary data in Access file PinmemberBahrudin Hrnjica10:45 10 Nov '06  
GeneralFinding the columns that make up an index PinmemberAlexEvans21:31 12 Oct '06  
GeneralRe: Finding the columns that make up an index PinmemberBahrudin Hrnjica11:39 13 Oct '06  
GeneralRe: Finding the columns that make up an index PinmemberAlexEvans14:49 13 Oct '06  
QuestionSafeArray doesn't work here PinmemberRBrostedt0:24 3 Aug '06  
AnswerRe: SafeArray doesn't work here PinmemberBahrudin Hrnjica2:29 3 Aug '06  
GeneralNice PinmemberDino685:22 6 Feb '06  
GeneralPublicity for free PinmemberAlexEvans13:37 31 Jan '06  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 28 Jan 2006
Article Copyright 2006 by Bahrudin Hrnjica
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid