VC用ADO存取显示jpg/bmp位图文件

2 篇文章 0 订阅

 周六和今天两天的时间,把数据库关于图片的存储和显示 实现了,虽然时间有点长,但是还是实现了。以下是网上找到的资料,很有用。

http://hi.baidu.com/%B0%A2%B3%ACyuch/blog/item/3a0d0845980f0744500ffe5b.html

第一步:首先是要打开一个位图文件,这里使用的控件用Picture控件,就是控件图标右边最上面那个,改ID号为IDC_PICTURE,然后定义两个成员变量
char *m_char;//图片文件指针
DWORD m_nFileLen;//图片长度
然后在函数中写入:
CFileDialog dlg(TRUE,NULL,NULL,0,"photo Files (*.jpg;*.bmp)|*.jpg;*.bmp|",this);
   if(IDOK==dlg.DoModal())
{
   m_path=dlg.GetPathName();
   m_bool=true;
}
   CWnd *pWnd = GetDlgItem(IDC_PICTURE);
   CRect rect;
   pWnd->GetClientRect(&rect);
   CDC *pDC = pWnd->GetDC();
   CFileStatus fstatus;
   CFile file;
   LONG cb;
   BOOL m_tm=false;
   IPicture *pPic;
   CString m_sPath;
   if (file.Open(m_path,CFile::modeRead)&& file.GetStatus(m_path,fstatus)&&((cb = fstatus.m_size) != -1))  
   {
  
   if(cb>1048576)   //可在此设置图片大小
   {
     m_tm=false;
     MessageBox("图片不能大于1M","提示!");
   }
   else
   {
    
     m_nFileLen=(UINT)cb;        
     HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb);
     LPVOID pvData = NULL;
     if (hGlobal != NULL)
     {
     if ((pvData = GlobalLock(hGlobal)) != NULL)
     {
       file.ReadHuge(pvData, cb);
       m_char=(char*)pvData;
       GlobalUnlock(hGlobal);
       CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);
       m_tm=true;
       // m_bool=true;
     }
     else
       AfxMessageBox("不是图片文件!");
     }
     else
     AfxMessageBox("申请内存失败!");
    
   }
   }  
   else
   AfxMessageBox("不是图片文件!");
   if(m_tm)
   {
   SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&pPic));
   OLE_XSIZE_HIMETRIC hmWidth;
   OLE_YSIZE_HIMETRIC hmHeight;
   pPic->get_Width(&hmWidth);
   pPic->get_Height(&hmHeight);  
   if(FAILED(pPic->Render(*pDC,0,0,rect.Width(),rect.Height(),0,hmHeight,hmWidth,-hmHeight,NULL)))
     AfxMessageBox("渲染图像失败!");
   pPic->Release();
   }
这里还有个小小的问题,就是当窗口出现重画的时候图片就会消失,可以把上面的代码加入到OnPaint函数中去;
接来就是保存文件(怎么访问数据库的可以去看下我空间里的"用ADO访问数据库"):
在Access数据库中把要放相片字段的类型改为OLE 类型(在SQL数据库改成相片类型).
m_RecordSet->AddNew();
char   *pBuf = m_char;//把图片的指针传给pBuf
   VARIANT   varBLOB;
   SAFEARRAY   *psa;
   SAFEARRAYBOUND rgsabound[1];
   if(pBuf)
   {    
   rgsabound[0].lLbound = 0;
   rgsabound[0].cElements = m_nFileLen;
   psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
   for (long i = 0; i < (long)m_nFileLen; i++)
     SafeArrayPutElement (psa, &i, pBuf++);
   varBLOB.vt = VT_ARRAY | VT_UI1;
   varBLOB.parray = psa;
   m_pRecordset->GetFields()->GetItem("读者相片")->AppendChunk(varBLOB);      
   }
   m_pRecordset->Update();

接下来就是把图片从数据库中取出来,在放图相的对话框中加入Picture控件,改ID为IDC_PICTURE,然后 在函数中写入:
IStream *pStm;
   long lDataSize = m_pRecordset->GetFields()->GetItem("读者相片")->ActualSize;
   if(lDataSize > 0)
   {
   _variant_t varBLOB;  
   varBLOB = theApp.m_data.m_pRecordset->GetFields()->GetItem("读者相片")->GetChunk(lDataSize);  
   if(varBLOB.vt == (VT_ARRAY | VT_UI1))
   {
     char *pBuf = NULL;
     SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
     HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, lDataSize);
     LPVOID pvData = NULL;
     if (hGlobal != NULL)
     {
     if ((pvData = GlobalLock(hGlobal)) != NULL)
     {
       memcpy(pvData,pBuf,lDataSize);
       SafeArrayUnaccessData (varBLOB.parray);
       GlobalUnlock(hGlobal);
       CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);
     }
     else
       AfxMessageBox("加载图片失败!");
     }
     else
     AfxMessageBox("申请内存失败!");
    
   }
   CWnd *pWnd = GetDlgItem(IDC_PICTURE);
   CRect rect;
   pWnd->GetClientRect(&rect);
   CDC *pDC = pWnd->GetDC();
   IPicture *pPic;
   if(SUCCEEDED(OleLoadPicture(pStm,lDataSize,TRUE,IID_IPicture,(LPVOID*)&pPic)))
   {
     OLE_XSIZE_HIMETRIC hmWidth;    
     OLE_YSIZE_HIMETRIC hmHeight;
     pPic->get_Width(&hmWidth);
     pPic->get_Height(&hmHeight);    
     if(FAILED(pPic->Render(*pDC,0,0,rect.Width(),rect.Height(),0,hmHeight,hmWidth,-hmHeight,NULL)))
     AfxMessageBox("渲染图像失败!");
     pPic->Release();
   }
   }
这样写也会出现当窗口重绘窗口图片就会消失的问题,可以把上面的函数写在OnPaint()中.整个显示,存取和访问图片的程序就已经完成了.

http://hi.baidu.com/roufei13/blog/item/6528919e0fb23aa4c9eaf4d8.html

    CoInitialize(NULL);

 

       _ConnectionPtr m_pConnect;

       try

       {

              // 创建Connection对象

              m_pConnect.CreateInstance("ADODB.Connection");

              // 设置连接字符串,必须是BSTR型或者_bstr_t类型

              _bstr_t strConnect = "Provider=SQLOLEDB.1;Password=111111;Persist Security Info=True;User ID=sa;Initial Catalog=Picture;Data Source=SHOWFLY\\SQL2005";

              m_pConnect->Open(strConnect,"","",adModeUnknown);

       }

       // 捕捉异常

       catch(_com_error e)

       {

              // 显示错误信息

              AfxMessageBox(e.Description());

       }

 

       CFile   fileAdd;

 

       if(fileAdd.Open("F:/20087610203.JPG",CFile::modeRead)==0)    //打开文件

              return;

 

       _variant_t   varChunk;

 

       long   m_nFileLen   =   fileAdd.GetLength();

       BYTE*   m_pBMPBuffer;

       m_pBMPBuffer = new BYTE[m_nFileLen];

 

       if(m_pBMPBuffer==NULL)

              return;

       fileAdd.Read(m_pBMPBuffer,m_nFileLen);

 

//向数据库添加图片

       _RecordsetPtr m_pRecordset;

       m_pRecordset.CreateInstance(__uuidof(Recordset));

 

       try{

              m_pRecordset->Open(_variant_t("dbo.userphoto"),_variant_t((IDispatch*)m_pConnect,true),adOpenKeyset,adLockOptimistic,adCmdTable);

       }

       catch(_com_error &e)

       {

              ::MessageBox(NULL,"无法打开userphoto表!","提示",MB_OK|MB_ICONWARNING);

       }

 

       char        *pBuf = (char*)m_pBMPBuffer;

       VARIANT              varBLOB;

       SAFEARRAY  *psa;

       SAFEARRAYBOUND    rgsabound[1];

 

       m_pRecordset->AddNew();                                              ///添加新记录

       m_pRecordset->PutCollect("username",_variant_t("小李"));             ///为新记录填充username字段

       m_pRecordset->PutCollect("old",_variant_t((long)28));                 ///填充old字段

       if(pBuf)

       {

              rgsabound[0].lLbound = 0;

              rgsabound[0].cElements = m_nFileLen;

              psa = SafeArrayCreate(VT_UI1, 1, rgsabound);                      ///创建SAFEARRAY对象

              for (long i = 0; i < (long)m_nFileLen; i++)

                     SafeArrayPutElement (psa, &i, pBuf++);                         ///pBuf指向的二进制数据保存到SAFEARRAY对象psa

              varBLOB.vt = VT_ARRAY | VT_UI1;                                   ///varBLOB的类型设置为BYTE类型的数组

              varBLOB.parray = psa;                                             ///varBLOB变量赋值

              m_pRecordset->GetFields()->GetItem("photo")->AppendChunk(varBLOB);///加入BLOB类型的数据

       }

       m_pRecordset->Update();                                              ///保存我们的数据到库中

 

 

//从数据库读出图片

       long   lDataLength = m_pRecordset->GetFields()->GetItem(_variant_t("photo"))->ActualSize;

 

       if (lDataLength>0)

       {

              _variant_t   varBLOB;

              varBLOB=m_pRecordset->GetFields()->GetItem(_variant_t("photo"))->GetChunk(lDataLength);

 

              if(varBLOB.vt== (VT_ARRAY|VT_UI1) && varBLOB.vt!=VT_EMPTY && varBLOB.vt!=VT_NULL )

              {

                     BYTE *pBuf = NULL;

                     pBuf = (BYTE*)GlobalAlloc(GMEM_FIXED,lDataLength);

 

                     SafeArrayAccessData(varBLOB.parray,(void   **)&pBuf);

 

                     CFile   outFile("D:/20087610203.bmp",CFile::modeCreate|CFile::modeWrite); //构造新文件,如果文件存在,则长度变为0

                     outFile.Write(pBuf,lDataLength);

                     outFile.Close();

 

                     SafeArrayUnaccessData (varBLOB.parray);

              }

       }

       m_pRecordset->Close();

 

       m_pConnect->Close();

 

       ::CoUninitialize();

http://www.cnblogs.com/-clq/archive/2011/08/27/2155342.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值