Click here to Skip to main content
15,867,704 members
Articles / Database Development / SQL Server
Article

Loading image files from a database, using ADO

Rate me:
Please Sign up or sign in to vote.
4.74/5 (22 votes)
27 Jan 2006CPOL1 min read 130.3K   3K   90   23
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Bosnia and Herzegovina Bosnia and Herzegovina
Bahrudin Hrnjica holds a Ph.D. degree in Technical Science/Engineering from University in Bihać.
Besides teaching at University, he is in the software industry for more than two decades, focusing on development technologies e.g. .NET, Visual Studio, Desktop/Web/Cloud solutions.

He works on the development and application of different ML algorithms. In the development of ML-oriented solutions and modeling, he has more than 10 years of experience. His field of interest is also the development of predictive models with the ML.NET and Keras, but also actively develop two ML-based .NET open source projects: GPdotNET-genetic programming tool and ANNdotNET - deep learning tool on .NET platform. He works in multidisciplinary teams with the mission of optimizing and selecting the ML algorithms to build ML models.

He is the author of several books, and many online articles, writes a blog at http://bhrnjica.net, regularly holds lectures at local and regional conferences, User groups and Code Camp gatherings, and is also the founder of the Bihac Developer Meetup Group. Microsoft recognizes his work and awarded him with the prestigious Microsoft MVP title for the first time in 2011, which he still holds today.

Comments and Discussions

 
Generaladding camera capture to this program Pin
suyun9029-Jun-09 20:03
suyun9029-Jun-09 20:03 
GeneralRe: adding camera capture to this program Pin
Member 268614322-Jan-10 1:33
Member 268614322-Jan-10 1:33 
AnswerRe: adding camera capture to this program Pin
RaviRanjanKr1-Mar-11 0:09
professionalRaviRanjanKr1-Mar-11 0:09 
Questionwhy should we put images in db? Pin
ikprog5-Feb-09 21:31
ikprog5-Feb-09 21:31 
AnswerRe: why should we put images in db? Pin
Theo Buys6-Nov-13 1:29
Theo Buys6-Nov-13 1:29 
Generalcomparing images in vb Pin
uet2-Mar-08 1:41
uet2-Mar-08 1:41 
AnswerRe: comparing images in vb Pin
RaviRanjanKr1-Mar-11 0:15
professionalRaviRanjanKr1-Mar-11 0:15 
GeneralNot compatible with Visual Studio 9 Pin
Patrickquinn121219-Feb-08 2:28
Patrickquinn121219-Feb-08 2:28 
GeneralRe: Not compatible with Visual Studio 9 Pin
Bahrudin Hrnjica15-Aug-08 9:10
professionalBahrudin Hrnjica15-Aug-08 9:10 
Questionwhy i can't download this source? Pin
c_glacier28-Jan-08 16:35
c_glacier28-Jan-08 16:35 
Generalnothing in Internet. strange Pin
BalinTomsk18-Sep-07 10:23
BalinTomsk18-Sep-07 10:23 
GeneralMySQL with TEXT type column Pin
AlexEvans6-Jul-07 12:48
AlexEvans6-Jul-07 12:48 
Using MFC / C++ with ADO accessing a MySQL database. I have in one table a column type TEXT. It seems however that the ActiveX or the MySQL driver (not sure which) is identifying that column as “adVarChar” instead of what I expected it to be “adLongVarChar” and subsequently, the process ends up with wrong data buffer.

Should I use maybe another data type for long text colimns?

Cheers
Alex

QuestionHow to Remove Image while saving record Pin
gargamehl17-Apr-07 14:44
gargamehl17-Apr-07 14:44 
GeneralDatas saved as Long Binary data in Access file [modified] Pin
Priyah8-Nov-06 0:03
Priyah8-Nov-06 0:03 
GeneralRe: Datas saved as Long Binary data in Access file Pin
Bahrudin Hrnjica10-Nov-06 10:45
professionalBahrudin Hrnjica10-Nov-06 10:45 
GeneralFinding the columns that make up an index Pin
AlexEvans12-Oct-06 21:31
AlexEvans12-Oct-06 21:31 
GeneralRe: Finding the columns that make up an index Pin
Bahrudin Hrnjica13-Oct-06 11:39
professionalBahrudin Hrnjica13-Oct-06 11:39 
GeneralRe: Finding the columns that make up an index Pin
AlexEvans13-Oct-06 14:49
AlexEvans13-Oct-06 14:49 
QuestionSafeArray doesn't work here Pin
RBrostedt3-Aug-06 0:24
RBrostedt3-Aug-06 0:24 
AnswerRe: SafeArray doesn't work here Pin
Bahrudin Hrnjica3-Aug-06 2:29
professionalBahrudin Hrnjica3-Aug-06 2:29 
GeneralNice Pin
Dino686-Feb-06 5:22
Dino686-Feb-06 5:22 
GeneralPublicity for free Pin
AlexEvans31-Jan-06 13:37
AlexEvans31-Jan-06 13:37 

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

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