亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++使用ADO實現存取圖片的方法

2020-02-24 14:26:30
字體:
來源:轉載
供稿:網友

我們在開發項目的時候需要從數據庫中讀取和顯示的圖片很多,但是C++將代碼從數據庫中的二進制數據轉換成本地存儲的原始圖像,今天武林技術頻道小編重點要說的是C++使用ADO實現存取圖片的方法,一起去跟隨武林技術頻道小編去了解一下吧。

本文就此問題一步一步地講一講解決的方法:

一、使用數據庫前的準備

我們使用ADO,是用_ConnectionPtr,_RecordsetPtr來操縱數據庫的。還有一個_CommandPtr,本程序沒有使用它。

為了使用ADO,需要導入ADO動態鏈接庫。在工程的stdafx.h文件中,添加如下代碼:

//導入ADO#import "C:/Program Files/Common Files/System/ado/msado15.dll"/rename_namespace("ADOCG")rename("EOF","EndOfFile")using namespace ADOCG;

這些代碼聲明,在這個工程中使用ADO但不使用ADO的名字空間,并且為了避免常數沖突,將常數EOF改名為adoEOF。

再有就是要建一個簡單的數據庫,名字叫TestImage,里面有一個表Images,這個表有三個字段,分別是ID,Name,ImageData。

二、連接數據庫

連接數據庫的代碼可以放入一個函數中,在想調用的地方調用。一般不推薦在CAPP類的Initalize()里連接數據庫,在退出程序時關閉數據庫連接。應該是在使用時連接,使用完馬上關閉。項目中m_pConn是_ConnectionPtr類型的變量。

BOOL OpenConnection(){if(m_pConn == NULL){m_pConn.CreateInstance("ADODB.Connection"); //創建_ConnectionPtr的一個實例}try{if(adStateClosed == m_pConn->State) //如果已關閉{m_pConn->Open("driver={SQL Server};Server=HP-CADD722B76A0;DATABASE=TestImage;UID=sa;PWD=sa","","",adModeUnknown); //因數據庫而異return true;}}catch(_com_error e){AfxMessageBox(_T("連接數據庫失敗!"));return false;}}

三、打開數據集,操縱數據庫

在使用_RecordSetPtr對象m_pRecord時,必須先創建這種對象的一個實例:

m_pRecord.CreateInstance( __uuidof(RecordSet) );CString strSQL;//獲取表中最大的id,下一次插入時就用id+1strSQL.Format(_T("Select count(*) as num, Max(ID) as maxid from Images"));try{m_pRecord->Open(strSQL.AllocSysString(), m_pConn.GetInterfacePtr(),adOpenDynamic, adLockUnspecified, adCmdText);}catch (_com_error e){AfxMessageBox(_T("讀取最大的id異常"));eturn;}//從RecordSet中獲取數據數目和當前數據庫中最大的ID。int num = m_pRecord->GetCollect("num");int maxid;if (num != 0){maxid = m_pRecord->GetCollect("maxid");}else{maxid = 0;}strSQL.Format(_T("Select * from Images where ID = %d"), maxid);//下面向數據庫中插入圖片等。//首先從數據庫中讀id最大的那條數據,主要目的是為了將RecordSet初始化m_pRecord.CreateInstance(__uuidof(Recordset));

上面這句一定要注意,因為上一次把一些數據放入m_pRecord中,這一次再放的時候,要重新創建一次,否則數據格式要么不匹配,要么保留有上一次的數據,定位困難。

m_pRecord->Open(strSQL.AllocSysString(), m_pConn.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText); //這是AddNew方法要求的CString imagepath = _T("F:/200713454/20090326.bmp");CString imagename = imagepath.Right(12);try{m_pRecord->AddNew(); //為記錄集添加新的一行,更新時就會把這條新紀錄放到數據庫中}catch (_com_error e) {AfxMessageBox(_T("不能插入一條新的記錄"));return;}try{//使用putcollect插入非圖像數據,使用SetImage2DB插入圖像數據m_pRecord->PutCollect("ID", _variant_t(maxid+1));m_pRecord->PutCollect("Name", _variant_t(imagename));SetImage2DB(imagepath);}catch (_com_error e){AfxMessageBox(_T("插入圖片有異常"));return;}m_pRecord->Update();//使用完畢,關閉m_pRecord,并設置為NULL,最后關閉數據庫連接m_pRecord->Close();m_pRecord = NULL;CloseConnection();

四、讀取圖片并存儲到本地計算機

要將數據庫中的二進制數據變為圖片,最簡單的方法就是用GDI+。GDI+有一個類是Image,可以用stream來創建對象,還可以用Save方法保存到本地,所以這個類很符合需要。

要使用GDI+,需要做些設置。首先在VS2005的項目屬性中,加上gdiplus.lib。

然后在stdafx.h中添加代碼

#include <GdiPlus.h>using namespace Gdiplus;

在CApp類添加兩個變量:

GdiplusStartupInput m_gdiplusstartUpInput;ULONG_PTR m_GdiplusToken;

在CApp的InitInstance函數中添加

GdiplusStartup(&m_GdiplusToken, &m_gdiplusstartUpInput, NULL);

在ExitInstance函數中添加

GdiplusShutdown(m_GdiplusToken);

以下是讀取圖片數據并保存到本地的代碼實現:

OpenConnection();m_pRecord.CreateInstance(__uuidof(Recordset));CString strSQL;strSQL.Format(_T("Select * from Images where ID = 1"));try{m_pRecord->Open(strSQL.AllocSysString(), m_pConn.GetInterfacePtr(),adOpenDynamic, adLockOptimistic, adCmdText);}catch (_com_error e){AfxMessageBox(_T("讀取圖片信息異常"));return;}LPVOID Data;char* pbuf = NULL;long lDatasize = m_pRecord->GetFields()->GetItem("ImageData")->ActualSize; //數據庫中圖像數據長度CString imagename = m_pRecord->GetCollect("Name").bstrVal;if (lDatasize > 0){_variant_t varBLOB;varBLOB = m_pRecord->GetFields()->GetItem("ImageData")->GetChunk(lDatasize);Data = new char[lDatasize+1];if (varBLOB.vt == (VT_ARRAY|VT_UI1)){SafeArrayAccessData(varBLOB.parray, (void **)&pbuf);memcpy(Data, pbuf, lDatasize);SafeArrayUnaccessData(varBLOB.parray);}}IStream* pStm;LONGLONG cb = lDatasize;HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb);LPVOID pvData;if (hGlobal != NULL){pvData = GlobalLock(hGlobal);memcpy(pvData, Data, cb);GlobalUnlock(hGlobal);CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);}else{AfxMessageBox(_T("Error"));return;}CLSID encoderClsid;GetEncoderClsid(L"image/bmp",&encoderClsid); //確定編碼格式是bmp格式Image image(pStm, TRUE);CString imagepath;imagepath.Format(_T("F:/200713454/%s"), imagename);image.Save(imagepath, &encoderClsid, NULL); //把image中的數據按照bmp編碼格式存到本地m_pRecord->Close();m_pRecord = NULL;CloseConnection();

上面存儲和讀取數據的代碼中用到了兩個函數,GetEncoderClsid和SetImage2DB。它們的實現如下:
這個函數和上面的存/取函數都是一個類的成員函數,而m_pConn和m_pRecord是這個類的成員變量,所以

void CDlgTest::SetImage2DB(CString path){VARIANT varChunk;SAFEARRAY* psa;SAFEARRAYBOUND rgsabound[1];CFile f(path.operator LPCTSTR(),CFile::modeRead);BYTE bval[ChunkSize+1];long uIsRead=0;while (1){uIsRead=f.Read(bval,ChunkSize);if (uIsRead==0) break;rgsabound[0].cElements=uIsRead;rgsabound[0].lLbound=0;psa=SafeArrayCreate(VT_UI1,1,rgsabound);for (long index=0;index<uIsRead;index++){if (FAILED(SafeArrayPutElement(psa,&index,&bval[index])))AfxMessageBox(_T("錯誤。"));}varChunk.vt =VT_ARRAY|VT_UI1;varChunk.parray=psa;try{m_pRecord->Fields->GetItem("ImageData")->AppendChunk(varChunk);}catch (_com_error e){AfxMessageBox(_T("錯誤。"));}::VariantClear(&varChunk);::SafeArrayDestroyData(psa);if (uIsRead<ChunkSize)break;}f.Close();}INT CDlgTest::GetEncoderClsid(const WCHAR* format, CLSID* pClsid){UINT num = 0; // number of image encodersUINT size = 0; // size of the image encoder array in bytesImageCodecInfo* pImageCodecInfo = NULL;GetImageEncodersSize(&num, &size);if(size == 0)return -1; // FailurepImageCodecInfo = (ImageCodecInfo*)(malloc(size));if(pImageCodecInfo == NULL)return -1; // FailureGetImageEncoders(num, size, pImageCodecInfo);for(UINT j = 0; j < num; ++j){if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ){*pClsid = pImageCodecInfo[j].Clsid;free(pImageCodecInfo);return j; // Success} }free(pImageCodecInfo);return -1; // Failure}以上就是C++使用ADO實現存取圖片的方法,如果你還想了解其他的專業知識,歡迎你隨時來武林技術頻道多加學習和了解,相信我們的內容一定會讓你滿意。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲成人av中文字幕| 亚洲精品之草原avav久久| 国产欧美日韩精品丝袜高跟鞋| 欧洲亚洲在线视频| 9.1国产丝袜在线观看| 久久免费视频在线| 国产精品一区=区| 91在线免费观看网站| 久久久精品久久| 日韩视频在线免费| 亚洲视频精品在线| 青青精品视频播放| 91视频国产一区| 日韩二区三区在线| 亚洲影院色在线观看免费| 久久艹在线视频| 日本在线观看天堂男亚洲| 欧美最顶级的aⅴ艳星| 久久精品久久久久| 亚洲欧洲美洲在线综合| 91精品久久久久久久久久另类| 亚洲美女精品成人在线视频| 日本三级韩国三级久久| 国产精品免费网站| 日韩视频免费大全中文字幕| 91色琪琪电影亚洲精品久久| 亚洲欧美日韩精品久久奇米色影视| 91精品国产免费久久久久久| 国产日韩亚洲欧美| 97色在线播放视频| 日av在线播放中文不卡| 欧美一区三区三区高中清蜜桃| 亚洲精品97久久| 久久99久久99精品中文字幕| 国产丝袜视频一区| 欧美激情按摩在线| 国产精品私拍pans大尺度在线| 91香蕉国产在线观看| 韩国三级日本三级少妇99| 日韩欧美在线第一页| 成人在线免费观看视视频| 国产精品精品视频| 揄拍成人国产精品视频| 色老头一区二区三区在线观看| 国产欧美日韩最新| 不卡av电影在线观看| 国产精品黄色影片导航在线观看| 九九热精品视频| 欧美精品www| 精品丝袜一区二区三区| 国产国语刺激对白av不卡| 69久久夜色精品国产69| 成人免费在线网址| 精品久久久一区二区| 91在线中文字幕| 亚洲理论片在线观看| 亚洲精品国精品久久99热一| 夜夜嗨av一区二区三区四区| 亚洲成人黄色在线| 欧美富婆性猛交| 国产精品美女www| 欧美性色视频在线| 亚洲一区二区三区视频播放| 91九色国产社区在线观看| 日韩av一区二区在线观看| 最近2019年日本中文免费字幕| 国产精品爽爽ⅴa在线观看| 亚洲成人久久一区| 欧亚精品中文字幕| 久久久亚洲影院| 亚洲视频自拍偷拍| 性欧美激情精品| 亚洲人成电影在线观看天堂色| 国产精品久久一| 日本精品视频在线播放| 91精品久久久久久久| 久久久久久久亚洲精品| 国产ts人妖一区二区三区| 日韩久久精品成人| 色偷偷偷综合中文字幕;dd| 国产日韩欧美中文| 国产狼人综合免费视频| 精品偷拍各种wc美女嘘嘘| 激情懂色av一区av二区av| 久久在线精品视频| 在线日韩日本国产亚洲| 日韩av免费在线观看| 亚洲午夜激情免费视频| 亚洲成av人乱码色午夜| 欧美日韩国产综合视频在线观看中文| 日韩av一区在线| 亚洲精品国产福利| 国产美女精品视频免费观看| 日本高清久久天堂| 久久精品99久久久久久久久| 久久久久久久999精品视频| 欧美大片大片在线播放| 国产精品久久久久久久久免费| 黑人欧美xxxx| 日韩电影在线观看中文字幕| 久久精品99久久香蕉国产色戒| 国产一区二区久久精品| 亚洲精品视频久久| 一区二区三区久久精品| 亚洲黄页网在线观看| 成人免费看吃奶视频网站| 国产精品成人免费电影| 欧美一级淫片videoshd| 国产日本欧美视频| 亚洲欧美激情一区| 色老头一区二区三区在线观看| 国语自产偷拍精品视频偷| 一区二区三区视频免费在线观看| 国产精品一区二区av影院萌芽| 夜夜嗨av色一区二区不卡| 日韩中文综合网| 在线日韩日本国产亚洲| 一区二区三区www| 国产999在线观看| 色妞在线综合亚洲欧美| 综合国产在线视频| 亚洲中国色老太| 日韩h在线观看| 91大神在线播放精品| 日韩欧美在线视频免费观看| 亚洲成av人片在线观看香蕉| 日韩麻豆第一页| 亚洲性生活视频在线观看| 91po在线观看91精品国产性色| 一区二区亚洲精品国产| 国产精品揄拍500视频| 亚洲综合第一页| 成人av资源在线播放| 国产日韩中文字幕在线| 亚洲免费人成在线视频观看| 欧美性感美女h网站在线观看免费| 亚洲一区二区久久久久久| 欧美裸体xxxx极品少妇| 中文字幕久热精品在线视频| 欧美精品在线免费| 国产在线视频欧美| 自拍亚洲一区欧美另类| 隔壁老王国产在线精品| 亚洲精品日韩欧美| 亚洲高清福利视频| 国内精品视频久久| 97免费视频在线| 久久亚洲精品一区二区| 欧美另类第一页| 日韩中文第一页| 中文字幕不卡av| 国产91精品久久久| 日本亚洲欧美成人| 成人乱人伦精品视频在线观看| 亚洲资源在线看| 91在线视频一区| 欧美大片免费观看在线观看网站推荐| 色狠狠av一区二区三区香蕉蜜桃| 久久久之久亚州精品露出| 欧美精品在线视频观看| 91亚洲人电影| 亚洲欧美另类人妖| 欧美又大又粗又长| 精品久久久久久久大神国产|