VC in the database programming, often need to deal with the image data in the database, the image from the database and display, image data and text fields are different, it is as an OLE field stored in the database, through the DataSet object member variables automatically exchanged image data, The resulting data is not directly visible, how to deal with image data, has been a difficult point in the database programming, the current VC database programming a lot of data, but rarely involved in the operation of image data, the author of a situation, combined with their own development of a project to solve the problem of how to display the image of the database, This article takes the operation Acess database as an example, explains own realization thought, hoped to have the help to the friend who likes the VC programming, in order to play the role.
To simplify the problem, there is only one OLE field named images in the table in the database. I use the DAO connection to manipulate the database, read the image data displayed in a dialog box, as for the use of ODBC, DAO or ADO, depending on the circumstances, but regardless of the use of the image to display the , the process of implementation is very similar. Due to the limited space, the article on how to implement the database connection no longer specific instructions, interested readers can refer to the VC database programming data. In the implementation process, you first define a CDaoRecordset subclass Cimagedata as follows:
Class Cimagedata:public CDaoRecordset
{
Public
Cimagedata (cdaodatabase* pdatabase = NULL);
Declare_dynamic (Cimagedata)
File://{{afx_field (Cimagedata, CDaoRecordset)
CByteArray m_images;//declare byte array to hold image data
File://}}afx_field
Overrides
ClassWizard generated virtual function overrides
File://{{afx_virtual (Cimagedata)
Public
Virtual CString getdefaultdbname ();
Virtual CString GetDefaultSQL ();
virtual void DoFieldExchange (cdaofieldexchange* pFX);
File://}}afx_virtual
The implementation of this class is:
Cimagedata:: Cimagedata (cdaodatabase* pdb)
: CDaoRecordset (PDB)
{
File://{{afx_field_init (Cimagedata)
m_nfields = 1;//database has only one field in the table
File://}}afx_field_init
m_nDefaultType = dbopendynaset;//Open a database in a dynamic set
}
CString Cimagedata::getdefaultdbname ()
{
Return _t ("E:images.mdb");/the default acess database is in E disk, named IMAGES
}
CString Cimagedata::getdefaultsql ()
{
Return _t ("[Table]");//default to open the table named "table" in the database
}
void Cimagedata::D ofieldexchange (cdaofieldexchange* PFX)
{
File://{{afx_field_map (Cimagedata)
Pfx->setfieldtype (CDaoFieldExchange::outputColumn);
DFX_Binary (PFX, _t ("[Images]"), m_images)//Exchange data in binary form between Images and m_images variables
File://}}afx_field_map
}
With this class, you can define the object to exchange data with the Image field in the database, and the function defined below Getimagedata () describes how to generate the image to be displayed based on the OLE field data that is being read. Note that the variable bitmap of the CBitmap class used in this function is a predefined global variable:
BOOL Cimagedlg:: Getimagedata (CByteArray & Dbarray)
{
CByteArray Array;
Array.copy (Dbarray);
int headerlen = + sizeof (bitmapfileheader); file://determines the starting position of the image header information
Array.removeat (0, Headerlen); Move to the starting position of the image header information
Bitmapinfoheader &bmiheader = * (Lpbitmapinfoheader) array.getdata ();
Bitmapinfo &bminfo = * (lpbitmapinfo) array.getdata ();
file://gets the header information of the image data
int ncolors=bmiheader.biclrused? Bmiheader.biclrused:1 "Bmiheader.bibitcount;
file://determine the number of colors in the image
LPVOID lpdibbits;
if (BmInfo.bmiHeader.biBitCount > 8)
Lpdibbits= (LPVOID) (Lpdword) (bminfo.bmicolors+bminfo.bmiheader.biclrused) +
((bmInfo.bmiHeader.biCompression = = Bi_bitfields) (3:0));
Else
Lpdibbits = (LPVOID) (bminfo.bmicolors + ncolors);
FILE://gets the specific data of each pixel of the image
CCLIENTDC DC (NULL);
Hbitmap hbmp = CreateDIBitmap (DC.M_HDC,
&bmiheader,
Cbm_init,
Lpdibbits,
&bminfo,
Dib_rgb_colors);
file://Generate bitmap Handles
Bitmap.attach (hbmp);//Associate the handle with the defined Bitmap object
Array.removeall (); file://free Memory
return TRUE;
}
With the above preparation, you can now implement the image display function, which is implemented as follows:
void Cimagedlg::onshowimage ()
{
Cimagedata db;//defines a Recordset object
Db. Open ();
Getimagedata (db.m_images);//To generate an Image object from a member variable of a Recordset object
file://The following is the image displayed in the fixed area of the dialog box
CPAINTDC DC (this);
if (!) ( Bitmap.m_hobject = = NULL))
{CDC dcmem;
Dcmem.createcompatibledc (&DC); File://create a Memory Image
cbitmap* Pbmpold;
BITMAP bmpsize;
Bitmap.getbitmap (&bmpsize); File://get Image Size
Pbmpold = Dcmem.selectobject (&bitmap);
dc. StretchBlt (&dcmem, 0, 0, bmpsize.bmwidth, Bmpsize.bmheight, srccopy);
Dcmem.selectobject (Pbmpold);
}
The database used in the above code is ACESS97, the program compiles and runs normally in Windows98, Visual c++6.0 environment.