新聞中心
在利用VC進行數(shù)據(jù)庫編程時,經(jīng)常需要處理數(shù)據(jù)庫中的圖像數(shù)據(jù),將該圖像從數(shù)據(jù)庫中讀取出來并顯示,圖像數(shù)據(jù)與文本字段不同,它是作為OLE字段在數(shù)據(jù)庫中存儲,通過數(shù)據(jù)集對象的成員變量自動交換得到的圖像數(shù)據(jù),得到的數(shù)據(jù)并不能直接顯示,如何處理圖像數(shù)據(jù),一直是數(shù)據(jù)庫編程中的一個難點。

成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比禮縣網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式禮縣網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋禮縣地區(qū)。費用合理售后完善,10多年實體公司更值得信賴。
目前關(guān)于VC進行數(shù)據(jù)庫編程的資料不少,但很少涉及圖像數(shù)據(jù)的操作,筆者針對一現(xiàn)狀,結(jié)合自己開發(fā)的一個項目,解決了如何顯示數(shù)據(jù)庫中的圖像這一問題,本文以操作ACESS數(shù)據(jù)庫為例子,講解一下自己的實現(xiàn)思路,希望對愛好VC編程的朋友們有所幫助,以起到拋磚引玉的作用。
為了簡化問題,該數(shù)據(jù)庫的表中只有一個名為Images的OLE字段,我使用DAO連接操作數(shù)據(jù)庫,讀取的圖像數(shù)據(jù)顯示在一個對話框上,至于使用ODBC、DAO還是ADO,這要根據(jù)具體情況而定,但無論使用哪一種,對圖像的顯示來說,實現(xiàn)的過程是大同小異的。
由于篇幅有限,文章中對如何實現(xiàn)數(shù)據(jù)庫的連接不再作具體的說明,有興趣的讀者朋友可以參考VC數(shù)據(jù)庫編程的資料。實現(xiàn)過程中,首先定義一個CDaoRecordset的子類 CimageData如下:
- class CimageData : public CDaoRecordset
- {
- public:
- CimageData (CDaoDatabase* pDatabase = NULL);
- DECLARE_DYNAMIC(CimageData)
- file://{{AFX_FIELD(CimageData, CDaoRecordset)
- CByteArray m_Images;//聲明字節(jié)數(shù)組用來存放圖像數(shù)據(jù)
- 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
該類的實現(xiàn)為:
- CimageData:: CimageData (CDaoDatabase* pdb)
- : CDaoRecordset(pdb)
- {
- file://{{AFX_FIELD_INIT(CimageData)
- m_nFields = 1;//數(shù)據(jù)庫的表中僅有一個字段
- file://}}AFX_FIELD_INIT
- m_nDefaultType = dbOpenDynaset;//以動態(tài)集方式打開數(shù)據(jù)庫
- }
- CString CimageData::GetDefaultDBName()
- {
- return _T("E:\\IMAGES.mdb");//默認的ACESS數(shù)據(jù)庫在E盤,名為IMAGES
- }
- CString CimageData::GetDefaultSQL()
- {
- return _T("[Table]");//默認打開數(shù)據(jù)庫中名為"Table"的表
- }
- void CimageData::DoFieldExchange(CDaoFieldExchange* pFX)
- {
- file://{{AFX_FIELD_MAP(CimageData)
- pFX->SetFieldType(CDaoFieldExchange::outputColumn);
- DFX_Binary(pFX, _T("[Images]"), m_Images);//以二進制方式在Images字段和m_Images變量間交換數(shù)據(jù)
- file://}}AFX_FIELD_MAP
- }
有了該類,就可以定義相應(yīng)的對象來與數(shù)據(jù)庫中的圖像字段交換數(shù)據(jù),下面定義的函數(shù)GetImageData()說明了如何根據(jù)讀取的OLE字段數(shù)據(jù)生成待顯示的圖像,需要注意的是該函數(shù)中使用的CBitmap類的變量Bitmap是預(yù)定義的一個全局變量:
- BOOL CImageDlg:: GetImageData(CByteArray & DBArray)
- {
- CByteArray Array;
- Array.Copy( DBArray);
- int HeaderLen = 78 + sizeof(BITMAPFILEHEADER); file://確定圖像頭信息的起始位置
- Array.RemoveAt( 0, HeaderLen ); // 移動到圖像頭信息的起始位置
- BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)Array.GetData() ;
- BITMAPINFO &bmInfo = *(LPBITMAPINFO)Array.GetData() ;
- file://得到圖像數(shù)據(jù)的頭信息
- int nColors=bmiHeader.biClrUsed ? bmiHeader.biClrUsed : 1 《 bmiHeader.biBitCount;
- file://確定圖像的顏色數(shù)
- 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://得到圖像各個像素的具體數(shù)據(jù)
- CClientDC dc(NULL);
- HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,
- &bmiHeader,
- CBM_INIT,
- lpDIBBits,
- &bmInfo,
- DIB_RGB_COLORS);
- file://生成位圖句柄
- Bitmap.Attach( hBmp );//將該句柄與定義的Bitmap對象聯(lián)系在一起
- Array.RemoveAll(); file://釋放內(nèi)存
- return TRUE;
- }
有了上面的準(zhǔn)備工作,現(xiàn)在可以實現(xiàn)圖像的顯示函數(shù)了,其實現(xiàn)如下:
- void CImageDlg::OnShowImage()
- {
- CimageData db;//定義記錄集對象
- db.Open();打開數(shù)據(jù)庫
- GetImageData(db.m_Images);//根據(jù)記錄集對象的成員變量生成圖像對象
- file://以下是在對話框的固定區(qū)域顯示圖像
- 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( 20, 20, 200, 200, &dcMem, 0, 0, BmpSize.bmWidth, BmpSize.bmHeight, SRCCOPY);
- dcMem.SelectObject( pbmpOld );
- }
以上代碼中使用的數(shù)據(jù)庫為ACESS97,程序在windows98、Visual C++6.0環(huán)境下編譯通過,運行正常。
【編輯推薦】
- VC++獲得當(dāng)前系統(tǒng)時間的幾種方案
- MVC+jQuery開發(fā)B/S系統(tǒng):表單提交
- 淺談怎樣加快C++代碼的編譯速度
- C/C++是程序員必須掌握的語言嗎?
- 再駁Linus:思科工程師對C++不得不說的事
網(wǎng)頁題目:VisualC++中實現(xiàn)對圖像數(shù)據(jù)的讀取顯示
URL網(wǎng)址:http://fisionsoft.com.cn/article/cdioscd.html


咨詢
建站咨詢
