国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

關于VC++的圖像數據訪問的研究

發布時間:2012-10-4 14:51    發布者:1770309616
關鍵詞: 圖像數據
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所示。
  圖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指令將此動態鏈接庫導入,具體代碼如下[1]:
  #import“c:\program files\common files
  \system\ado\msado15.dll”\no_namespace\rename(“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;data
  source = 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類對較復雜的odbc
  api進行了封裝,提供了簡化的調用接口,方便了數據庫應用程序的開發[2]。
  mfc
  odbc類主要包括cdatabase類、crecordset類和cfieldexchange類。cdatabase類的主要功能是建立與數據庫的連接;crecordset類針對數據源中記錄集,它負責對記錄的操作;cfieldexchange類負責crecordset與數據源的數據交換。
  4.2 配置odbc數據源
  用odbc管理器定義了一個數據源,管理器根據數據源所在的位置,數據庫類型及odbc驅動器等信息,建立起odbc與具體數據庫之間的聯系。在windows
  xp的系統中,配置odbc數據源的過程為:控制面板—性能和維護—管理工具—數據源(odbc)。
  4.3 odbc連接數據庫
  創建cdatabase對象并連接數據庫:
  cdatabase m_db;//定義的數據庫全局變量
  cbitmap bitmap;
  //定義的圖像類全局變量,存儲圖像數據
  m_db.open(null, false, false, “odbc;driver={microsoft access
  driver (*.mdb)};
  dbq= picture.mdb”);
  4.4 圖像數據的存儲
  首先做一些變量的定義:
  m_ picture為picture字段對應的長二進制成員變量;
  m_hdata用來存放picture字段的數據;
  m_dwdatalength為picture字段的實際長度。
  圖像數據的存儲過程可以分為以下三步:
  (1) 打開圖像數據,獲得數據長度;
  (2) 申請緩沖區,把文件讀入此緩沖區;
  (3) 通過調用update()刷新數據庫記錄。
  具體實現代碼如下:
  static char based_code szfilter[]=“bitmap files
  (*.bmp)|*.bmp||”;
  cdbimages dbimages(m_db);
  cfiledialog fd(true,null,null,0,szfilter,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技術和mfc
  odbc在access中存儲和讀取圖像數據的方法以及部分程序代碼。這兩種訪問方法在vc++
  7.0的環境下進行調試結果顯示,使用ado來訪問數據庫中的圖像數據更加的方便,更加的高效,使用mfc
  odbc方法訪問大對象數據的速度相對較慢。在開發擴展時會發現mfc
  odbc不能用于其他的非關系數據庫,使用的范圍相對較窄。這兩種方法還可以應用于其他二進制大對象數據的訪問。

電子工程網
本文地址:http://m.qingdxww.cn/thread-98537-1-1.html     【打印本頁】

本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
您需要登錄后才可以發表評論 登錄 | 立即注冊

廠商推薦

  • Microchip視頻專區
  • 使用SAM-IoT Wx v2開發板演示AWS IoT Core應用程序
  • 使用Harmony3加速TCP/IP應用的開發培訓教程
  • 集成高級模擬外設的PIC18F-Q71家族介紹培訓教程
  • 探索PIC16F13145 MCU系列——快速概覽
  • 貿澤電子(Mouser)專區
關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 这里只有精品66 | 男女污污无遮挡免费观看 | 日韩网站在线观看 | 亚洲天堂91 | 中文字幕欧美日韩高清 | 日本高清免费在线视频 | 免费一级做a爰片久久毛片 免费一级在线观看 | 一级特级女人18毛片免费视频 | 国产中字 | 华人91视频 | 青青操手机看 | 亚洲视频欧洲视频 | 日本人的色道www免费一区 | 四虎影视精品永久免费 | 555夜色555亚洲夜色 | 国产又长又粗又爽免费视频 | 欧美色欧美亚洲高清在线视频 | 性俄罗斯hd | 免费国产成人高清在线观看不卡 | 999精品久久久中文字幕蜜桃 | 999热这里全都是精品 | 国内精品一区二区三区αv 国内精品一区二区三区 | 日韩福利小视频 | 九色在线视频观看 | 一级全黄毛片 | 九九热在线视频免费观看 | 亚洲欧美一区在线 | 一级特黄aaa大片在线观看 | 国产麻豆精品免费视频 | re99热久久这里只有精品 | 日日射日日干 | 国产三级视频网站 | 4hu影院永久在线播放 | 亚洲欧美日韩一区高清中文字幕 | 日韩精品在线一区二区 | 亚洲色图视频在线 | 欧美巨大精品欧美一区二区 | 99午夜高清在线视频在观看 | 欧美国产一区二区三区 | 四虎永久免费网站免费观看 | 久久影视精品 |