OPENCV+VS2008+SQLserver图片存储数据库开发
OPENCV+VS2008+SQLserver 图片存储数据库开发 本人是做图像处理方向的,图像存储的数据库开发是一次尝试,开发平台用的是 OPENCV+VS2008+SQLserver , OPENCV 对图片的读取比较方便,而且支持 bmp , jpg , tiff , png 等多种图像格式,数据库访问技术采用
OPENCV+VS2008+SQLserver图片存储数据库开发
本人是做图像处理方向的,图像存储的数据库开发是一次尝试,开发平台用的是OPENCV+VS2008+SQLserver,OPENCV对图片的读取比较方便,而且支持bmp,jpg,tiff,png等多种图像格式,数据库访问技术采用的是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。安装SQL2005,VS2008.
第二步:在SQL2005里新建一个新的数据库,名字为management,在management数据库中添加一个表,名字为personalmessage,字段有name,sex,student_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需要用户名和密码登陆的话,里面的ID和password要对应你自己的SQL登录名和密码,Data Source也要特别注意,代表你数据库注册的服务器名,我的是WIDOWSXP-CC3F79。以后在程序中就可以直接调用GetRecordset来获得命令对象指针,从而可以方便的对数据库进行操作。
第四步:图片存入数据库
图片存入数据库的原理就是:把图片转换成二进制形式,存入到image变量中。
由于VC对bmp格式的图片处理比较方便,因此我用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++)
SafeArrayPutElement (psa, &i, pBuf++);
varBLOB.vt = VT_ARRAY | VT_UI1;
varBLOB.parray = psa;
m_pRecordset->GetFields()->GetItem("picture")->AppendChunk(varBLOB);
}
delete [] pBuffer; //删掉堆上申请的那一块内存
pBuf=0; //以防二次乱用
}
f.Close(); //这里一定要记得先关闭文件,后面再Remove,否则会出现共享冲突
CFile::Remove( L"D://SQL//adotest//adotest//1.bmp" );
}
m_pRecordset->Update();
m_CAdoConn.ExitConnect();
}
MessageBox(L"添加成功");
}
else
{
MessageBox(L"无信息添加");
}
m_student_number=m_name=m_sex="";
m_pic1=0;
UpdateData(FALSE);
}
第五步:读取图片
代码如下:
long nSize = m_pRecordset->GetFields()->GetItem("picture")->ActualSize;
if(nSize > 0)
{
_variant_t varBLOB;
varBLOB = m_pRecordset->GetFields()->GetItem("picture")->GetChunk(nSize);
if(varBLOB.vt == (VT_ARRAY | VT_UI1))
{
if(BYTE *pBuffer = new BYTE [nSize+1]) ///重新申请必要的存储空间
{
char *pBuf = NULL;
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
memcpy(pBuffer,pBuf,nSize); ///复制数据到缓冲区m_pBMPBuffer
SafeArrayUnaccessData (varBLOB.parray);
delete [] pBuffer;
pBuf=0;
}
//输出文件
_variant_t varChunk;
HRESULT hr;
BYTE *pBuf = NULL;
pBuf = (BYTE*)GlobalAlloc(GMEM_FIXED,nSize);
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
CFile outFile(L"D://SQL//adotest//adotest//2.bmp",CFile::modeCreate|CFile::modeWrite);
LPSTR buffer = (LPSTR)GlobalLock((HGLOBAL)pBuf);
outFile.Write(buffer,nSize);
GlobalUnlock((HGLOBAL)pBuf);
outFile.Close();
SafeArrayUnaccessData (varBLOB.parray);
}
IplImage *img=cvLoadImage("D://SQL//adotest//adotest//2.bmp");
DrawPicToHDC(img,IDC_pic2);
m_pic2=img;
CFile::Remove( L"D://SQL//adotest//adotest//2.bmp" );
}
在整个过程中碰到的几个问题:
1. 在数据库读取过程中,如果某个记录为NULL的话,如果直接读取转换就会出错,所以得预先判断,代码如下:
VARIANT var = m_pRecordset->Fields->Item["name"]->GetValue();
if ( var.vt != VT_NULL )
{
m_showname=(LPCTSTR)(_bstr_t)m_pRecordset->GetCollect((_bstr_t)"name");
}
2. 文件打开之后要记得f.close(),否则就会出现共享冲突()
3. 图像显示在图像控件上的时候,定义的IplImage变量要记得初始化。
4. 载入的位图如果在文件中打开了rc就会出现opened in another editor,解决办法就是在文件视图中,把rc中的bmp关掉就OK了(这个问题因为我把一副图片设为了对话框的背景,然后把图片删除后造成的)
5. 还有就是几个变量类型转换的问题,像CString转 char*,_bstr_t与CString互转,我的程序里都有体现,另外一篇文章我也做了说明。
6. 图像的显示用的是
void CadotestDlg::DrawPicToHDC(IplImage *img, UINT ID) //用于在ID所指定的窗口上显示图片
{
CDC *pDC = GetDlgItem(ID)->GetDC();
HDC hDC= pDC->GetSafeHdc();
CRect rect;
GetDlgItem(ID)->GetClientRect(&rect);
CvvImage cimg;
cimg.CopyOf(img);
cimg.DrawToHDC(hDC,&rect);
ReleaseDC(pDC);
}

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











소셜 미디어의 지속적인 발전으로 Xiaohongshu는 점점 더 많은 젊은이들이 자신의 삶을 공유하고 아름다운 것을 발견할 수 있는 플랫폼이 되었습니다. 많은 사용자들이 이미지 게시 시 자동 저장 문제로 고민하고 있습니다. 그렇다면 이 문제를 해결하는 방법은 무엇입니까? 1. Xiaohongshu에 게시할 때 사진이 자동으로 저장되는 문제를 해결하는 방법은 무엇입니까? 1. 캐시 지우기 먼저 Xiaohongshu의 캐시 데이터를 지워볼 수 있습니다. 단계는 다음과 같습니다. (1) Xiaohongshu를 열고 오른쪽 하단에 있는 "내" 버튼을 클릭합니다. (2) 개인 센터 페이지에서 "설정"을 찾아 클릭합니다. 캐시 지우기' 옵션을 선택하고 확인을 클릭하세요. 캐시를 삭제한 후 샤오홍슈에 다시 진입하여 사진을 올려 자동 저장 문제가 해결되었는지 확인해 보세요. 2. Xiaohongshu 버전을 업데이트하여 Xiaohongshu를 확인하세요.

Douyin 짧은 동영상의 인기로 인해 댓글 영역의 사용자 상호 작용이 더욱 다채로워졌습니다. 일부 사용자는 자신의 의견이나 감정을 더 잘 표현하기 위해 댓글로 이미지를 공유하기를 원합니다. 그렇다면 TikTok 댓글에 사진을 게시하는 방법은 무엇입니까? 이 기사에서는 이 질문에 대해 자세히 답변하고 몇 가지 관련 팁과 예방 조치를 제공합니다. 1. Douyin 댓글에 사진을 어떻게 게시하나요? 1. Douyin 열기: 먼저 Douyin 앱을 열고 계정에 로그인해야 합니다. 2. 댓글 영역 찾기: 짧은 동영상을 탐색하거나 게시할 때 댓글을 달고 싶은 위치를 찾아 "댓글" 버튼을 클릭하세요. 3. 댓글 내용 입력: 댓글 영역에 댓글 내용을 입력합니다. 4. 사진 전송 선택: 댓글 내용 입력 인터페이스에 "사진" 버튼 또는 "+" 버튼이 표시됩니다.

Apple의 최근 iPhone은 선명한 디테일, 채도 및 밝기로 추억을 포착합니다. 그러나 때로는 이미지가 덜 선명하게 보일 수 있는 몇 가지 문제가 발생할 수 있습니다. iPhone 카메라의 자동 초점 기능이 크게 발전하여 사진을 빠르게 촬영할 수 있게 되었지만, 특정 상황에서는 카메라가 실수로 잘못된 피사체에 초점을 맞춰 원치 않는 영역에서 사진이 흐릿해질 수 있습니다. iPhone의 사진이 일반적으로 초점이 맞지 않거나 선명도가 부족한 경우 다음 게시물을 통해 사진을 더 선명하게 만드는 데 도움이 될 것입니다. iPhone에서 사진을 더 선명하게 만드는 방법 [6가지 방법] 기본 사진 앱을 사용하여 사진을 정리할 수 있습니다. 더 많은 기능과 옵션을 원하신다면

파워포인트에서는 그림을 하나씩 표시하는 것이 일반적인 기술인데, 이는 애니메이션 효과를 설정하면 가능하다. 이 가이드에서는 기본 설정, 이미지 삽입, 애니메이션 추가, 애니메이션 순서 및 타이밍 조정 등 이 기술을 구현하는 단계를 자세히 설명합니다. 또한 트리거 사용, 애니메이션 속도 및 순서 조정, 애니메이션 효과 미리보기 등의 고급 설정 및 조정이 제공됩니다. 이러한 단계와 팁을 따르면 사용자는 PowerPoint에서 그림이 차례로 표시되도록 쉽게 설정할 수 있으므로 프레젠테이션의 시각적 효과가 향상되고 청중의 관심을 끌 수 있습니다.

Foxit PDF Reader 소프트웨어도 사용하고 계십니까? 그렇다면 Foxit PDF Reader가 PDF 문서를 jpg 이미지로 변환하는 방법을 알고 계십니까? 다음 기사에서는 변환 방법에 관심이 있는 사람들을 위해 Foxit PDF Reader가 PDF 문서를 jpg 이미지로 변환하는 방법을 설명합니다. jpg 이미지를 보려면 아래를 방문하여 살펴보시기 바랍니다. 먼저 Foxit PDF Reader를 시작한 다음 상단 도구 모음에서 "기능"을 찾은 다음 "PDF를 다른 사람에게 보내기" 기능을 선택하십시오. 다음으로 "Foxit PDF 온라인 변환"이라는 웹 페이지를 엽니다. 페이지 오른쪽 상단의 "로그인" 버튼을 클릭하여 로그인한 후 "PDF를 이미지로" 기능을 활성화하세요. 그런 다음 업로드 버튼을 클릭하고 이미지로 변환하려는 PDF 파일을 추가한 후 "변환 시작"을 클릭하세요.

JavaScript를 사용하여 이미지의 드래그 및 확대/축소 기능을 구현하는 방법은 무엇입니까? 최신 웹 개발에서는 이미지 드래그 및 확대/축소가 일반적인 요구 사항입니다. JavaScript를 사용하면 이미지에 드래그 및 확대/축소 기능을 쉽게 추가하여 더 나은 사용자 경험을 제공할 수 있습니다. 이 기사에서는 구체적인 코드 예제와 함께 JavaScript를 사용하여 이 기능을 구현하는 방법을 소개합니다. HTML 구조 먼저, 그림을 표시하고 추가하려면 기본 HTML 구조가 필요합니다.

이 웹사이트는 3월 7일 화웨이의 데이터 스토리지 제품 라인 사장인 Zhou Yuefeng 박사가 최근 MWC2024 컨퍼런스에 참석하여 웜 데이터(WarmData)와 콜드 데이터(ColdData)용으로 설계된 차세대 OceanStorArctic 자전 스토리지 솔루션을 구체적으로 시연했다고 보도했습니다. Huawei의 데이터 스토리지 제품 라인 사장 Zhou Yuefeng은 일련의 혁신적인 솔루션을 출시했습니다. 이미지 출처: 이 사이트에 첨부된 Huawei의 공식 보도 자료는 다음과 같습니다. 이 솔루션의 가격은 자기 테이프보다 20% 저렴하며, 전력 소비는 하드 디스크보다 90% 낮습니다. 해외 기술 매체인 blockandfiles에 따르면, Huawei 대변인은 자기전기 저장 솔루션에 대한 정보도 공개했습니다. Huawei의 자기전자 디스크(MED)는 자기 저장 매체의 주요 혁신입니다. 1세대 ME

WPS 사무용 소프트웨어를 사용할 때 하나의 양식만 사용되는 것이 아니라 텍스트에 표와 그림을 추가할 수 있고 표에 그림도 추가할 수 있다는 사실을 발견했습니다. 이 모든 것이 함께 사용되어 전체 문서의 내용을 구성합니다. 문서에 두 개의 그림을 삽입하고 나란히 정렬해야 하는 경우 더 풍부해 보입니다. 다음 과정에서는 이 문제를 해결할 수 있습니다: wps 문서에 두 장의 그림을 나란히 배치하는 방법입니다. 1. 먼저 WPS 소프트웨어를 열고 조정하려는 사진을 찾아야 합니다. 사진을 마우스 왼쪽 버튼으로 클릭하면 메뉴 표시줄이 나타나며 "페이지 레이아웃"을 선택합니다. 2. 텍스트 줄 바꿈에서 "Tight 줄 바꿈"을 선택합니다. 3. 필요한 모든 사진이 "단단한 텍스트 줄 바꿈"으로 설정되었는지 확인한 후 사진을 적절한 위치로 끌어서 첫 번째 사진을 클릭할 수 있습니다.
