Visual C++中實現對映像資料的讀取顯示

來源:互聯網
上載者:User

在利用VC進行資料庫編程時,經常需要處理資料庫中的映像資料,將該映像從資料庫中讀取出來並顯示,映像資料與文字欄位不同,它是作為OLE欄位在資料庫中儲存,通過資料集對象的成員變數自動交換得到的映像資料,得到的資料並不能直接顯示,如何處理映像資料,一直是資料庫編程中的一個痛點,目前關於VC進行資料庫編程的資料不少,但很少涉及映像資料的操作,筆者針對一現狀,結合自己開發的一個項目,解決了如何顯示資料庫中的映像這一問題,本文以操作ACESS資料庫為例子,講解一下自己的實現思路,希望對愛好VC編程的朋友們有所協助,以起到拋磚引玉的作用。
為了簡化問題,該資料庫的表中只有一個名為Images的OLE欄位,我使用DAO串連操作資料庫,讀取的映像資料顯示在一個對話方塊上,至於使用ODBC、DAO還是ADO,這要根據具體情況而定,但無論使用哪一種,對映像的顯示來說,實現的過程是大同小異的。由於篇幅有限,文章中對如何?資料庫的串連不再作具體的說明,有興趣的讀者朋友可以參考VC資料庫編程的資料。實現過程中,首先定義一個CDaoRecordset的子類 CimageData如下:
class CimageData : public CDaoRecordset
{
public:
CimageData (CDaoDatabase* pDatabase = NULL);
DECLARE_DYNAMIC(CimageData)
file://{{AFX_FIELD(CimageData, CDaoRecordset)
CByteArray m_Images;//聲明位元組數組用來存放映像資料
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
該類的實現為:
CimageData:: CimageData (CDaoDatabase* pdb)
: CDaoRecordset(pdb)
{
file://{{AFX_FIELD_INIT(CimageData)
m_nFields = 1;//資料庫的表中僅有一個欄位
file://}}AFX_FIELD_INIT
m_nDefaultType = dbOpenDynaset;//以動態集方式開啟資料庫
}
CString CimageData::GetDefaultDBName()
{
return _T("E:\\IMAGES.mdb");//預設的ACESS資料庫在E盤,名為IMAGES
}
CString CimageData::GetDefaultSQL()
{
return _T("[Table]");//預設開啟資料庫中名為"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變數間交換資料
file://}}AFX_FIELD_MAP
}

有了該類,就可以定義相應的對象來與資料庫中的映像欄位交換資料,下面定義的函數GetImageData()說明了如何根據讀取的OLE欄位資料產生待顯示的映像,需要注意的是該函數中使用的CBitmap類的變數Bitmap是預定義的一個全域變數:
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://得到映像資料的頭資訊
int nColors=bmiHeader.biClrUsed ? bmiHeader.biClrUsed : 1 《 bmiHeader.biBitCount;
file://確定映像的顏色數
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://得到映像各個像素的具體資料
CClientDC dc(NULL);
HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,
&bmiHeader,
CBM_INIT,
lpDIBBits,
&bmInfo,
DIB_RGB_COLORS);
file://產生位元影像控制代碼
Bitmap.Attach( hBmp );//將該控制代碼與定義的Bitmap對象聯絡在一起
Array.RemoveAll(); file://釋放記憶體
return TRUE;
}
有了上面的準備工作,現在可以實現映像的顯示函數了,其實現如下:
void CImageDlg::OnShowImage()
{
CimageData db;//定義記錄集對象
db.Open();開啟資料庫
GetImageData(db.m_Images);//根據記錄集對象的成員變數產生映像對象
file://以下是在對話方塊的固定地區顯示映像
CPaintDC dc(this);
if (!(Bitmap.m_hObject == NULL))
{ CDC dcMem;
dcMem.CreateCompatibleDC( &dc );file://createa Memory Image
CBitmap* pbmpOld ;
BITMAP BmpSize ;
Bitmap.GetBitmap(&BmpSize);file://getImage Size
pbmpOld = dcMem.SelectObject(&Bitmap);
dc.StretchBlt( 20, 20, 200, 200, &dcMem, 0, 0, BmpSize.bmWidth, BmpSize.bmHeight, SRCCOPY);
dcMem.SelectObject( pbmpOld );
}
以上代碼中使用的資料庫為ACESS97,程式在windows98、VisualC++6.0環境下編譯通過,運行正常。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.