欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

OPENCV+VS2008+SQLserver图片存储数据库开发

程序员文章站 2022-04-20 14:20:40
...

OPENCV+VS2008+SQLserver 图片存储数据库开发 本人是做图像处理方向的,图像存储的数据库开发是一次尝试,开发平台用的是 OPENCV+VS2008+SQLserver , OPENCV 对图片的读取比较方便,而且支持 bmp , jpg , tiff , png 等多种图像格式,数据库访问技术采用

OPENCV+VS2008+SQLserver图片存储数据库开发

本人是做图像处理方向的,图像存储的数据库开发是一次尝试,开发平台用的是OPENCV+VS2008+SQLserverOPENCV对图片的读取比较方便,而且支持bmpjpgtiffpng等多种图像格式,数据库访问技术采用的是ADO,下面我将详细的介绍整个开发过程。

第一步:安装opencv2.0并把cv.lib,cxcore.lib,highgui.lib 这三个库加入到工程里面,具体操作步骤参照http://www.opencv.org.cn/index.php/VC_2008_Express%E4%B8%8B%E5%AE%89%E8%A3%85OpenCV2.0。安装SQL2005VS2008.

第二步:SQL2005里新建一个新的数据库,名字为management,在management数据库中添加一个表,名字为personalmessage,字段有namesexstudent_number

Picture四个字段,前三个字段为字符型,后一个字段为image类型。

第三步:连接数据库,采用ADO方式

新建了一个类CADOConn,从Cobject派生,并增加以下四个成员函数:

_RecordsetPtr GetRecordset(_bstr_t bstrSQL,_bstr_t DB_Name);//得到命令对象指针

void ExitConnect(); //退出连接

BOOL OnInitADOConn(_bstr_t DB_Name); //初始化连接

BOOL Execute(_bstr_t bstrSQL,_bstr_t DB_Name); //执行sql语言

BOOL CADOConn::Execute(_bstr_t bstrSQL,_bstr_t DB_Name)

{

try

{

if (m_pConnection==NULL)

OnInitADOConn(DB_Name);

m_pConnection->Execute(bstrSQL,NULL,adCmdText);

// m_pConnection->Execute((LPCSTR)bstrSQL, NULL, adExecuteNoRecords);

}

catch (_com_error e)

{

AfxMessageBox(e.ErrorMessage());

return false;

}

return TRUE;

}

BOOL CADOConn::OnInitADOConn(_bstr_t DB_Name)

{

::CoInitialize(NULL);

try

{

m_pConnection.CreateInstance(__uuidof(Connection));

m_pConnection->PutCursorLocation(adUseClient);

_bstr_t connectionstring = "Provider=sqloledb;Data Source=";

connectionstring += _T("WIDOWSXP-CC3F79");

connectionstring += ";Initial Catalog=";

connectionstring += DB_Name;

connectionstring += ";User Id=sa";

connectionstring += ";Password=82877882";

connectionstring += ";";

m_pConnection->Open(connectionstring,"","",adConnectUnspecified);

/* m_pConnection->ConnectionString="driver={SQL Server};server="";datebase="+DB_Name;

m_pConnection->Open("","","",NULL);*/

}

catch (...)

{

AfxMessageBox(_T("初始化出错"));

return false;

}

return TRUE;

}

void CADOConn::ExitConnect()

{

m_pConnection->Close();

::CoUninitialize();

}

_RecordsetPtr CADOConn::GetRecordset(_bstr_t bstrSQL,_bstr_t DB_Name)

{

try

{

if(m_pConnection==NULL)

OnInitADOConn(DB_Name);

m_pRecordset.CreateInstance(__uuidof(Recordset));

m_pRecordset->Open(bstrSQL, _variant_t( (IDispatch *) m_pConnection,true), adOpenKeyset,adLockOptimistic, adCmdText);

}

catch (_com_error e)

{

AfxMessageBox(e.ErrorMessage());

//return m_pRecordset=NULL;

}

return m_pRecordset;

}

值得注意的是,在OnInitADOConn函数中,如果你的SQL需要用户名和密码登陆的话,里面的IDpassword要对应你自己的SQL登录名和密码,Data Source也要特别注意,代表你数据库注册的服务器名,我的是WIDOWSXP-CC3F79。以后在程序中就可以直接调用GetRecordset来获得命令对象指针,从而可以方便的对数据库进行操作。

第四步:图片存入数据库

图片存入数据库的原理就是:把图片转换成二进制形式,存入到image变量中。

由于VCbmp格式的图片处理比较方便,因此我用opencv读取完之后先把图片转换成bmp格式,读取二进制一般都是以文件形式读取,这里我投机取巧了一下,先把图片以bmp格式存放到某个路径中,然后用CFile以文件形式读取,存储到数据库之后再删除掉,删除用的是:CFile::Remove。如果大家有什么好方法还请告知,谢谢!

位图的读取可以参照http://www.programbbs.com/bbs/tree20-5675-29114.htm

我的代码如下:

void CadotestDlg::OnBnClickedadd()

{

UpdateData(TRUE);

if(m_name!="")

{

CString strSQL;

CADOConn m_CAdoConn;

_RecordsetPtr m_pRecordset;

//重新添加一个新的记录

strSQL=_T("select * from personalmessage");

m_pRecordset=m_CAdoConn.GetRecordset((_bstr_t)strSQL,(_bstr_t)("management"));

m_pRecordset->AddNew();

m_pRecordset->PutCollect((_bstr_t)"name",(_bstr_t)m_name);

m_pRecordset->PutCollect((_bstr_t)"sex",(_bstr_t)m_sex);

m_pRecordset->PutCollect((_bstr_t)"student_number",(_bstr_t)m_student_number);

if(m_pic1)

{

cvSaveImage("D://SQL//adotest//adotest//1.bmp",m_pic1);

//保存在"management"数据库中的"personalmessage",字段名"picture"

CFile f;

// TODO: Add your control notification handler code here

CString FilePathName("D://SQL//adotest//adotest//1.bmp");

CFileException e;

if(f.Open(FilePathName, CFile::modeRead | CFile::typeBinary, &e))

{

int nSize = f.GetLength(); //先得到文件长度

BYTE * pBuffer = new BYTE [nSize]; //按文件的大小在堆上申请一块内存

if (f.Read(pBuffer, nSize) > 0 ) //把文件读到pBuffer(堆上申请一块内存)

{

BYTE *pBuf = pBuffer; ///下面这一大段是把pBuffer里的数据放到库中

VARIANT varBLOB;

SAFEARRAY *psa;

SAFEARRAYBOUND rgsabound[1];

if(pBuf)

{

rgsabound[0].lLbound = 0;

rgsabound[0].cElements = nSize;

psa = SafeArrayCreate(VT_UI1, 1, rgsabound);

for (long i = 0; i long)nSize; i++)