0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用ado技术和mfc odbc技术的VC++图像数据访问研究

电子设计 来源:电子产品世界 作者:佚名 2020-02-25 08:07 次阅读

1 、引言

在许多项目开发中,由于存在着大量的数据需要存储,通常采用数据库来存储这些数据,使得数据库技术被越来越广泛地应用。在这些数据中有简单的文本文件,只需通过api的简单编程即可实现,但也存在许多大对象数据,比如图像、音频视频等,其存储形式有所不同。作为大对象数据的图像数据,一般以blob(二进制大对象,binary large object)形式存储,例如access数据库中ole对象数据类型、sql server数据库中的image数据类型等。在vc++ 7.0的环境下,为了高效快捷的访问图像数据,需要采用合适的数据库访问技术。

在vc++中标准的访问数据库技术有很多种,根据开发的项目,采用了数据库技术中最常见有效的两种技术ado技术和mfc odbc在access数据库中访问图像数据。

2、 图像数据访问原理

虽然图像数据的格式有多种,例如bmp、jpg和gif等格式,但都可以看成是二进制流,即blob类型。blob类型数据需要占用较大的硬盘空间和内存,对存储效率和查询速度都有很大的影响。

图像数据的访问分存储和读取两个过程。在存储过程中,由于存放图像数据的字段是可变长度(长度一般为0~2g)的blob类型,无法直接存储,必须首先将存储在文件中的图像数据以二进制流的形式读到缓冲区中,然后再将缓冲区中的图像数据添加到access数据库中的ole对象中。在读取过程中,将存放在access数据库中的图像数据读到缓冲区中,然后在显示在用户界面上。图像数据的访问原理如图1所示。

使用ado技术和mfc odbc技术的VC++图像数据访问研究

图1 图像数据访问原理图

3、 应用ado访问图像数据

3.1 ado的介绍

ado(activex data objects)是microsoft数据库应用程序开发的接口,是建立在ole db技术之上的高层数据库访技术,简化了编程,且有利于程序的可移植性及可扩充性。

ado包括connection对象、command对象、parameter对象、recordset对象、field对象、error对象、property对象以及相应的集合对象,这些对象被封装在_connection -ptr接口、_commndptr接口和_recordsetptr接口这三个基本接口中。

3.2 ado连接数据库

(1) 导入ado库

使用ado前需要在stdafx.h头文件中导入该库,只需利用import指令将此动态链接库导入,具体代码如下:

#import“c:program filescommon filessystemadomsado15.dll”o_namespaceename(“eof”,“adoeof”)

(2) 初始化com库

ado本身是一个com组件,在使用时需要初始化com库,需要调用coinitialize函数来实现。

:: coinitialize(null);

(3) 创建connection对象并连接数据库

创建connection对象:

_connectionptr m_pconnection;

m_pconnection.createinstanc -e(“adodb.connection”);

连接数据库:

_pconnection-》open(“provide -r=microsoft.jet.oledb.4.0;datasource = picture.mdb”, “”,“”, admodeunknown);

(4) 执行操作

m_precordset.createinstance(“adodb.recordset”);

m_precordset-》open((_variant_t)strsql,_variant_t((idispatch*)theapp.m_pconnection,true),adopendynamic,adlockoptimistic,adcmdtext);

3.3 图像数据的存储

对于一般数据,可以通过recordset对象的getcollect()和putcollect()函数来对数据进行存储和读取,而对于图像数据,就需要使用field对象中的appendchunk函数来进行存储和getchunk函数来进行读取。图像数据的存储过程可以分为以下三步:

(1) 打开图像数据,获得数据长度;申请缓冲区,把文件读入此缓冲区。

(2) 构造一个一维数组,把缓冲区中的数据拷贝到数组中,然后构造一个变体对象,用数组来对此对象赋值。

(3) 调用appendchunk函数,把数据存入recordset对象的本地缓冲区。

具体实现代码如下:

if(m_pic.m_ipicture != null) m_pic.freepicturedata();

if(f.open(m_strphotopath, cfile::moderead |

cfile::typebinary, &e)) //打开了一个图像文件

{nsize = f.getlength();//先得到图像数据长度

byte * pbuffer = new byte [nsize];//根据数据的长度申请缓冲区

if (f.read(pbuffer, nsize) 》 0 )//把图像数据读到缓冲区

{byte *pbuf = pbuffer;//把pbuffer里的jpg数据放到库中

variant varblob;

safearray *psa;

safearraybound rgsabound[1];//创建safearray对象

if(pbuf)

{rgsabound[0].llbound = 0;

rgsabound[0].celements = nsize;

psa = safearraycreate(vt_ui1, 1, rgsabound);

for (long i = 0; i 《 (long)nsize; i++)safearrayputelement (psa, &i, pbuf++);

varblob.vt = vt_array | vt_ui1;

varblob.parray = psa;

m_precordset-》getfields()-》getitem(“picture”)-》appendchunk(varblob);

m_precordset-》update();//更新数据库

}

delete [] pbuffer; //释放缓冲区

pbuf=0;

}

f.close();

}

3.4 图像数据的读取

图像数据的读取过程可以分为以下三歩:

(1) 获得picture字段中图像文件的实际长度。

(2) 调用getchunk函数,返回变体对象。

(3) 获得数组数据指针,把数据写入打开的文件中。

具体实现代码如下:

long nsize=m_precordset-》getfields()-》getitem(“picture ”)-》actualsize;//获得图像文件的长度

if(nsize1 》 0)

{ varblob=m_precordset-》getfields()-》getitem

(“picture ”)-》getchunk(nsize);//获得varblob的值

if(varblob.vt == (vt_array | vt_ui1))

{char *pbuf = null;

lpvoid pbuf2 = null;

safearrayaccessdata(varblob.parray,

(void **)&pbuf);//获得数组数据指针

hglobal=globalalloc(gmem_moveable,nsize);

pbuf2 = globallock(hglobal);

memcpy(pbuf2,pbuf,nsize1);//复制数据到缓冲区

::globalunlock(hglobal);

safearrayunaccessdata (varblob.parray);

hr=::createstreamonhglobal( hglobal,true, &pstream );

hr=::oleloadpicture( pstream, nsize1, true, iid_ipicture, (lpvoid * )&ppicture );

ppicture-》render(pdc-》m_hdc,0,0,rect.width(),rect.height(),0,nheight,nwidth,-nheight,null);//将图像数据显示在用户界面

}

}

4 、应用mfc odbc访问图像数据

4.1 mfc odbc的介绍

odbc(open database connect-ivity)是微软公司开放服务结构中有关数据库的一个组成部分。mfc的odbc类对较复杂的odbcapi进行了封装,提供了简化的调用接口,方便了数据库应用程序的开发。

mfcodbc类主要包括cdatabase类、crecordset类和cfieldexchange类。cdatabase类的主要功能是建立与数据库的连接;crecordset类针对数据源中记录集,它负责对记录的操作;cfieldexchange类负责crecordset与数据源的数据交换。

4.2 配置odbc数据源

用odbc管理器定义了一个数据源,管理器根据数据源所在的位置,数据库类型及odbc驱动器信息,建立起odbc与具体数据库之间的联系。在windowsxp的系统中,配置odbc数据源的过程为:控制面板—性能和维护—管理工具—数据源(odbc)。

4.3 odbc连接数据库

创建cdatabase对象并连接数据库:

cdatabase m_db;//定义的数据库全局变量

cbitmap bitmap;//定义的图像类全局变量,存储图像数据

m_db.open(null, false, false, “odbc;driver={microsoft accessdriver (*.mdb)};

dbq= picture.mdb”);

4.4 图像数据的存储

首先做一些变量的定义:

m_ picture为picture字段对应的长二进制成员变量;

m_hdata用来存放picture字段的数据;

m_dwdatalength为picture字段的实际长度。

图像数据的存储过程可以分为以下三步:

(1) 打开图像数据,获得数据长度;

(2) 申请缓冲区,把文件读入此缓冲区;

(3) 通过调用update()刷新数据库记录。

具体实现代码如下:

static char based_code s***ilter[]=“bitmap files(*.bmp)|*.bmp||”;

cdbimages dbimages(m_db);

cfiledialog fd(true,null,null,0,s***ilter,this);

if (idok != fd.domodal()) return;

dbimages.open();

dbimages.addnew();

cfile fileimage;

cfilestatus filestatus;

fileimage.open(fd.getpathname(), cfile::moderead);

fileimage.getstatus(filestatus);//获得打开图像文件的状态

dbimages.m_ picture.m_dwdatal -ength =filestatus.m_size;

hglobal hglobal=globalalloc(gptr,filestatus.m_size);//分配内存

dbimages.m_ picture.m_hdata = globallock(hglobal);//锁定内存

fileimage.readhuge(dbimages.m_picture.m_hdata,filestatus.m_size);//向缓冲区读取图像数据

dbimages.setfielddirty(&dbimages.m_ picture);//修改标志数据库

dbimages.setfieldnull(&dbim -ages.m_ picture,false);

dbimages.update();//刷新数据库的记录

globalunlock(hglobal);

dbimages.close();

4.5 图像数据的读取

图像数据的读取过程可以分为以下三步:

(1) 定义临时文件。

(2) 向临时文件中存放从数据库中读取到的图像数据。

(3) 取出图像数据,获得图像数据的宽度和高度。

具体实现代码如下:

cdbimages dbimages(m_db);

cstring strfilename ;

i=1;

strfilename.format(“%s”,i)dbimages.open();

if (dbimages.iseof())afxmessagebox(“unable to get image from picture”);

else{char tmppath[_max_path 1];

gettemppath(_max_path,tmppath);

strfilename.insert(0,tmppath);

cfile outfile(strfilename,cfile::modecreate

|cfile::modewrite);

lpstr buffer=(lpstr)globallock(dbimages.m_ picture.m_hdata);

outfile.writehuge(buffer,dbima -ges.m_picture.m_dwdatalength);

globalunlock(dbimages.m_ picture.m_hdata);

outfile.close();

hbitmap hbm=(hbitmap)::loa -dimage(null,strfilename,image_bitmap, 0, 0, lr_loadfromfile);

if (bitmap.attach(hbm)) { bitmap bm;

bitmap.getbitmap(&bm); //获得图像的尺寸

bitmap.setbitmapdimension(bm.bmwidth,bm.bmheight);//获得图像的宽度和高度

}

5 、结束语

介绍了使用ado技术和mfcodbc在access中存储和读取图像数据的方法以及部分程序代码。这两种访问方法在vc++7.0的环境下进行调试结果显示,使用ado来访问数据库中的图像数据更加的方便,更加的高效,使用mfcodbc方法访问大对象数据的速度相对较慢。在开发扩展时会发现mfcodbc不能用于其他的非关系数据库,使用的范围相对较窄。这两种方法还可以应用于其他二进制大对象数据的访问。

责任编辑:gt


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    6848

    浏览量

    88758
  • 视频
    +关注

    关注

    6

    文章

    1930

    浏览量

    72779
  • 存储
    +关注

    关注

    13

    文章

    4237

    浏览量

    85603
收藏 人收藏

    评论

    相关推荐

    C,C++,VC,VC++,MFC,API......

    C,C++,VC,VC++,MFC,API......发现总有人把这些东西搞混,简单解释一下.C,C++都是编程语言,两者是不同的,不要认为C++是C的升级.C是面向过程的,C++是面向对象(封装
    发表于 10-07 11:09

    使用MFC ODBC访问数据

    使用MFC ODBC访问数据库在VC环境下运行程序前,必须注册ODBC
    发表于 10-15 11:40

    使用ODBC API访问数据

    使用ODBC API访问数据库要运行程序,必须将数据库文件与可执行文件放在同一个目录下,在VC开发环境中运行时,同样需要把
    发表于 10-15 11:42

    ADO数据存储模块的问题

    数据存储模块出现错误提示:ADO Connection Execute.vi->SQL Execute.vi->数值写入数据库(字符串时间).vi中的Exception occured
    发表于 05-30 12:02

    VC6数据库综合开发资料相关资料下载

    VC6数据库综合开发资料目录 用VC++6.0开发多表联接的数据库应用程序《使用OLEDB编写数据库应用程序》《在Visual C++中用
    发表于 09-17 08:55

    什么是ODBC/MFC?

    什么是ODBC/MFC?
    发表于 11-11 07:47

    深入ADO.NET开发高级数据访问技术

    深入ADO.NET开发高级数据访问技术
    发表于 01-08 09:19 0次下载
    深入<b class='flag-5'>ADO</b>.NET开发高级<b class='flag-5'>数据</b><b class='flag-5'>访问</b><b class='flag-5'>技术</b>

    基于VC++MFC的上位机与PLC的通讯系统The Com

    本文介绍了用VC++MFC开发的上位机和PLC的通讯系统,给出了系统的通讯原理和系统的软件设计方法。实践证明整个系统运行稳定,实用性和可扩展性强。关键词:PLC;VC++;MFC;通
    发表于 05-26 13:13 33次下载

    基于VC++MFC 的上位机与PLC 的通讯系统

    本文介绍了用VC++MFC 开发的上位机和PLC 的通讯系统,给出了系统的通讯原理和系统的软件设计方法。实践证明整个系统运行稳定,实用性和可扩展性强。关键词:PLC VC++ MFC
    发表于 06-04 10:49 42次下载

    基于VC++ADO的燃气调压站管理系统开发

    本文介绍了一个基于VisualC++ 6.0 开发平台的管理系统数据库的开发过程,该系统采用ADO 数据访问技术,实现了
    发表于 08-15 09:08 27次下载

    利用ADO实现对多个数据库的访问

    本文分析了在做实际项目中所遇到的问题,提出了可行的解决方法。主要介绍了利用ADO Connection和ADO Recordset 对象访问多个数据库中多个表单的灵活
    发表于 09-10 16:12 15次下载

    ADO简介,什么是ADO,ADO是什么意思?

    ADO 简介 1、ADO是什么ADO(ActiveX Data Object)是OLE DB数据访问方式 的一种主要对象模型。
    发表于 05-10 11:01 1.9w次阅读
    <b class='flag-5'>ADO</b>简介,什么是<b class='flag-5'>ADO</b>,<b class='flag-5'>ADO</b>是什么意思?

    ADO.NET数据访问技术

    ADO.NET是在.NET Framework上访问数据库的一组类库,它利用.NET Data Provider(数据提供程序)以进行数据
    发表于 03-26 15:15 16次下载

    vc++应用程序和使用vc++设计的MFC计时器和计算机程序免费下载

    本文档的主要内容详细介绍的是vc++应用程序和使用vc++设计的MFC计时器和计算机程序免费下载。
    发表于 12-24 08:00 15次下载
    <b class='flag-5'>vc++</b>应用程序和使用<b class='flag-5'>vc++</b>设计的<b class='flag-5'>MFC</b>计时器和计算机程序免费下载

    VC+ADO+ORACLE开发讲解

    VC+ADO+ORACLE开发讲解(电源技术发展)-该文档为VC+ADO+ORACLE开发讲解文档,是一份还算不错的参考文档,感兴趣的可以下载看看,,,,,,,,,,,,,,,,,,
    发表于 09-28 09:20 2次下载
    <b class='flag-5'>VC+ADO</b>+ORACLE开发讲解