您的位置:首页 > 编程语言 > C语言/C++

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

2014-12-29 19:00 330 查看


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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: