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);
}