VC++把图像内容保存在数据库的例子

VC++把图像内容保存在数据库的例子

http://www.codefans.net/articles/1911.shtml


 

VC++结合Access,把图片数据保存在Access数据库中,插入图像数据保存在数据库的相关字段中,这样移植软件比较方便,不过会使数据库迅速变大,可根据你的软件需求选择使用,下面是代码:

 

 

#include "stdafx.h"

#include "InsertImage.h"

#include "InsertImageDlg.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

class CAboutDlg : public CDialog

{

public:

       CAboutDlg();

       enum{ IDD = IDD_ABOUTBOX };

       protected:

       virtualvoid DoDataExchange(CDataExchange* pDX);

protected:

       DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() :CDialog(CAboutDlg::IDD)

{

}

voidCAboutDlg::DoDataExchange(CDataExchange* pDX)

{

       CDialog::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

END_MESSAGE_MAP()

CInsertImageDlg::CInsertImageDlg(CWnd*pParent /*=NULL*/)

       :CDialog(CInsertImageDlg::IDD, pParent)

{

       m_hIcon= AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

voidCInsertImageDlg::DoDataExchange(CDataExchange* pDX)

{

       CDialog::DoDataExchange(pDX);

       DDX_Control(pDX,IDC_IMAGE, m_Image);

       DDX_Control(pDX,IDC_EDIT1, m_Path);

       DDX_Control(pDX,IDC_COMBO1, m_Combo);

       //}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CInsertImageDlg, CDialog)

       ON_WM_SYSCOMMAND()

       ON_WM_PAINT()

       ON_WM_QUERYDRAGICON()

       ON_BN_CLICKED(IDC_BUTSELECT,OnButselect)

       ON_BN_CLICKED(IDC_BUTINSERT,OnButinsert)

       ON_WM_CLOSE()

       ON_CBN_SELCHANGE(IDC_COMBO1,OnSelchangeCombo1)

END_MESSAGE_MAP()

BOOL CInsertImageDlg::OnInitDialog()

{

       CDialog::OnInitDialog();

       ASSERT((IDM_ABOUTBOX& 0xFFF0) == IDM_ABOUTBOX);

       ASSERT(IDM_ABOUTBOX< 0xF000);

       CMenu*pSysMenu = GetSystemMenu(FALSE);

       if(pSysMenu != NULL)

       {

              CStringstrAboutMenu;

              strAboutMenu.LoadString(IDS_ABOUTBOX);

              if(!strAboutMenu.IsEmpty())

              {

                     pSysMenu->AppendMenu(MF_SEPARATOR);

                     pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX, strAboutMenu);

              }

       }

       SetIcon(m_hIcon,TRUE);   

       SetIcon(m_hIcon,FALSE);

       OnInitADOConn();

       _bstr_tsql;

       sql= "select * from Picture";

       m_pRecordset.CreateInstance(__uuidof(Recordset));

       m_pRecordset->Open(sql,m_pConnection.GetInterfacePtr()

              ,adOpenDynamic,adLockOptimistic,adCmdText);

       inti=0;

       while(m_pRecordset->adoEOF==0)

       {

              m_Combo.InsertString(i,(char*)(_bstr_t)m_pRecordset->GetCollect("图片名称"));

              m_pRecordset->MoveNext();

              i++;

       }

       m_pRecordset->Close();

       returnTRUE;

}

void CInsertImageDlg::OnSysCommand(UINTnID, LPARAM lParam)

{

       if((nID & 0xFFF0) == IDM_ABOUTBOX)

       {

              CAboutDlgdlgAbout;

              dlgAbout.DoModal();

       }

       else

       {

              CDialog::OnSysCommand(nID,lParam);

       }

}

void CInsertImageDlg::OnPaint()

{

       if(IsIconic())

       {

              CPaintDCdc(this);

              SendMessage(WM_ICONERASEBKGND,(WPARAM) dc.GetSafeHdc(), 0);

              intcxIcon = GetSystemMetrics(SM_CXICON);

              intcyIcon = GetSystemMetrics(SM_CYICON);

              CRectrect;

              GetClientRect(&rect);

              intx = (rect.Width() - cxIcon + 1) / 2;

              inty = (rect.Height() - cyIcon + 1) / 2;

              dc.DrawIcon(x,y, m_hIcon);

       }

       else

       {

              CDialog::OnPaint();

       }

}

HCURSOR CInsertImageDlg::OnQueryDragIcon()

{

       return(HCURSOR) m_hIcon;

}

void CInsertImageDlg::OnButselect()

{

       CFileDialogdlg(true,"bmp",NULL,OFN_HIDEREADONLY |

              OFN_OVERWRITEPROMPT,"位图文件(*.bmp)|*.bmp",this);

       if(dlg.DoModal() == IDOK)

       {

              CStringstrText   = dlg.GetPathName();//取得图片的完整路径

              m_Path.SetWindowText(strText);

              m_StrName= dlg.GetFileName();

              HBITMAPm_hBitmap = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),strText,

                     IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTCOLOR|LR_DEFAULTSIZE);

              if(m_hBitmap != NULL)

              {

                     //使用控件显示图片

                     m_Image.SetBitmap(m_hBitmap);

              }

       }

}

void CInsertImageDlg::OnInitADOConn()

{

       try

       {

              m_pConnection.CreateInstance("ADODB.Connection");//创建连接对象实例

              _bstr_tstrConnect="DRIVER={Microsoft Access Driver (*.mdb)};\

                     uid=;pwd=;DBQ=Database.mdb;";

              m_pConnection->Open(strConnect,"","",adModeUnknown);//打开数据库

       }

       catch(_com_error e)//捕捉错误

       {

              AfxMessageBox(e.Description());//弹出错误

       }

}

void CInsertImageDlg::OnButinsert()

{

       try

       {

              CStringPath;

              m_Path.GetWindowText(Path);

              if(Path.IsEmpty())

              {

                     MessageBox("图片路径不能为空.","提示");

                     return;

              }

              char*m_pBuffer;

              //定义文件对象

              CFilefile;

              //以只读方式打开文件

              if(!file.Open(Path,CFile::modeRead))

              {

                     MessageBox("无法打开BMP文件");

                     return;

              }

              //用于保存文件长度

              DWORDm_filelen;

              //读取文件长度

              m_filelen= file.GetLength();

              //根据文件长度分配数组空间

              m_pBuffer= new char[m_filelen + 1];

              //读取BMP文件到m_pBuffer中

              if(file.ReadHuge(m_pBuffer,m_filelen)!=m_filelen)

              {

                     MessageBox("读取BMP文件是出现错误");

                     return;

              }

              file.Close();

              _bstr_tsql;

              sql= "select*from Picture";

              m_pRecordset.CreateInstance(__uuidof(Recordset));

              m_pRecordset->Open(sql,m_pConnection.GetInterfacePtr()

                     ,adOpenDynamic,adLockOptimistic,adCmdText);

              //添加新行

              m_pRecordset->AddNew();

              VARIANTvarblob;

              SAFEARRAY*psa;

              SAFEARRAYBOUNDrgsabound[1];

              rgsabound[0].lLbound= 0;

              rgsabound[0].cElements= m_filelen;

              //创建数组

              psa= SafeArrayCreate(VT_UI1,1,rgsabound);

              //将m_pBuffer中的图像数据写入数组psa

              for(longi=0;i<(long)m_filelen;i++)

              {

                     SafeArrayPutElement(psa,&i,m_pBuffer++);

              }

              varblob.vt= VT_ARRAY|VT_UI1;

              varblob.parray= psa;

              m_pRecordset->GetFields()->GetItem("图片名称")->Value =(_bstr_t)m_StrName;

              m_pRecordset->GetFields()->GetItem("图片路径")->Value =(_bstr_t)Path;

              //调用AppendChunk()函数将图像数据写入Photo字段

              m_pRecordset->GetFields()->GetItem("图片数据")->AppendChunk(varblob);

              //更新数据库

              m_pRecordset->Update();

              m_pRecordset->Close();

       }

       catch(...)

       {

              MessageBox("操作失败");

              return;

       }

       m_Combo.InsertString(m_Combo.GetCount(),m_StrName);

       MessageBox("操作成功.");

}

void CInsertImageDlg::OnClose()

{

       m_pConnection->Close();

       CDialog::OnClose();

}

void CInsertImageDlg::OnSelchangeCombo1()

{

       HBITMAPm_hBitmap;

       CStringname;

       m_Combo.GetLBText(m_Combo.GetCurSel(),name);

       _bstr_tsql;

       sql= "select*from Picture where 图片名称='"+name+"' ";

       m_pRecordset.CreateInstance(__uuidof(Recordset));

       m_pRecordset->Open(sql,m_pConnection.GetInterfacePtr()

              ,adOpenDynamic,adLockOptimistic,adCmdText);

       //读取图像字段的实际大小

       longlDataSize = m_pRecordset->GetFields()->GetItem("图片数据")->ActualSize;

       char*m_pBuffer;  //定义缓冲变量

       if(lDataSize> 0)

       {

              //从图像字段中读取数据到varBLOB中

              _variant_tvarBLOB;

              varBLOB= m_pRecordset->GetFields()->GetItem("图片数据")->GetChunk(lDataSize);

              if(varBLOB.vt== (VT_ARRAY | VT_UI1))

              {

                     if(m_pBuffer= new char[lDataSize+1])      //分配必要的存储空间

                     {

                            char*pBuf = NULL;

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

                            memcpy(m_pBuffer,pBuf,lDataSize);///复制数据到缓冲区m_pBuffer

                            SafeArrayUnaccessData(varBLOB.parray);

 

                            //将数据转换为HBITMAP格式

                            LPSTRhDIB;

                            LPVOIDlpDIBBits;

                            BITMAPFILEHEADERbmfHeader;  //用于保存BMP文件头信息,包括类型、大小、位移量等

                            DWORDbmfHeaderLen;  //保存文件头的长度

                            bmfHeaderLen= sizeof(bmfHeader);  //读取文件头的长度

                            //将m_pBuffer中文件头复制到bmfHeader中

                            strncpy((LPSTR)&bmfHeader,(LPSTR)m_pBuffer, bmfHeaderLen);

                            if(bmfHeader.bfType != (*(WORD*)"BM"))  //如果文件类型不对,则返回

                            {

                                   MessageBox("BMP文件格式不准确");

                                   return;

                            }

                            hDIB= m_pBuffer + bmfHeaderLen;  //将指针移至文件头后面

                            //读取BMP文件的图像数据,包括坐标及颜色格式等信息到BITMAPINFOHEADER对象

                            BITMAPINFOHEADER&bmiHeader = *(LPBITMAPINFOHEADER)hDIB;

                            //读取BMP文件的图像数据,包括坐标及颜色格式等信息到BITMAPINFO对象

                            BITMAPINFO&bmInfo = *(LPBITMAPINFO)hDIB ;

                            //根据bfOffBits属性将指针移至文件头后

                            lpDIBBits= (m_pBuffer) + ((BITMAPFILEHEADER *)m_pBuffer)->bfOffBits;

                            CClientDCdc(this);  //生成一个与当前窗口相关的CClientDC,用于管理输出设置

                            //生成DIBitmap数据

                            m_hBitmap= CreateDIBitmap(dc.m_hDC,&bmiHeader,CBM_INIT,lpDIBBits,&bmInfo,DIB_RGB_COLORS);

                     }

              }

       }

       m_Image.SetBitmap(m_hBitmap);

}

 

 

 



















  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值