zoukankan      html  css  js  c++  java
  • 把图片存/取至数据库

    http://blog.chinaunix.net/uid-607545-id-2088102.html

    http://blog.csdn.net/eryadabendan/article/details/6749939

    关于图片的存储和显示 

    第一步:首先是要打开一个位图文件,这里使用的控件用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()中.整个显示,存取和访问图片的程序就已经完成了.

      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

  • 相关阅读:
    01数据结构——绪论
    07机器学习实战k-means
    OpenJudge 2756 二叉树
    Poj/OpenJudge 1094 Sorting It All Out
    OpenJudge 2811 熄灯问题 / Poj 1222 EXTENDED LIGHTS OUT
    OpenJudge/Poj 1083 Moving Tables
    OpenJudge 2810(1543) 完美立方 / Poj 1543 Perfect Cubes
    Poj/OpenJudge 1042 Gone Fishing
    Poj 1013 Counterfeit Dollar / OpenJudge 1013(2692) 假币问题
    Poj 1017 / OpenJudge 1017 Packets/装箱问题
  • 原文地址:https://www.cnblogs.com/wxl845235800/p/7430008.html
Copyright © 2011-2022 走看看