• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    IPicture控件實現(xiàn)圖片數(shù)據(jù)在數(shù)據(jù)庫中的存取

    2015-04-17 22:39:24凡揚華
    機械工程與自動化 2015年6期
    關(guān)鍵詞:二進制字段數(shù)據(jù)流

    凡揚華

    (同濟大學 軟件學院,上海 201900)

    IPicture控件實現(xiàn)圖片數(shù)據(jù)在數(shù)據(jù)庫中的存取

    凡揚華

    (同濟大學 軟件學院,上海 201900)

    針對數(shù)據(jù)庫應用程序開發(fā)中以往圖片類型數(shù)據(jù)存取方法存在一致性、安全性及完整性較差的缺點,利用數(shù)據(jù)庫管理系統(tǒng)提供的一種名為二進制大對象(BLOB)的字段類型,提出了一種利用IPicture控件實現(xiàn)圖片數(shù)據(jù)在數(shù)據(jù)庫大對象字段中的存取方法。

    數(shù)據(jù)庫訪問技術(shù);IPicture控件;圖片數(shù)據(jù)

    0 引言

    為了便于建模,一般的數(shù)據(jù)庫管理系統(tǒng)都提供了字符型字段、數(shù)值型字段等常見數(shù)據(jù)類型,有的數(shù)據(jù)庫管理系統(tǒng),比如DB2,也提供了用于保存復雜結(jié)構(gòu)的數(shù)據(jù)類型,如圖片、文檔等,將對象保存為長二進制數(shù)據(jù)類型。但對于二進制數(shù)據(jù)類型,不能采用像一般數(shù)據(jù)類型那樣的賦值操作,因而存取起來比較復雜。一種普遍采用的變通方法是將本地圖像(文檔)文件的路徑作為字符串保存在數(shù)據(jù)庫字段中,然后根據(jù)字符串,索引數(shù)據(jù)庫外的圖像(文檔)文件完成訪問功能。但該方法有一個非常明顯的缺點,即大對象文件并不是保存在數(shù)據(jù)庫字段中,數(shù)據(jù)庫管理系統(tǒng)提供的有關(guān)數(shù)據(jù)的安全性、完整性及一致性等良好特性未能得到有效實施。本文利用IPicture控件,從分析其核心功能入手,結(jié)合內(nèi)存數(shù)據(jù)交換技術(shù),介紹了一種將圖像文件直接存入數(shù)據(jù)庫字段的技術(shù)。

    1 控件IPicture的功能

    IPicture控件采用微軟COM接口技術(shù),封裝了常見格式(如*.jpg,*.bmp,*.png等)的圖片操作,下面對相關(guān)的主要函數(shù)接口進行介紹。

    1.1 從文件中載入圖片

    從文件中載入圖片使用的OleLoadPicture函數(shù)如下:

    OleLoadPicture(pStm,dwSize,FALSE,IID_IPicture,(LPVOID*)&m_pPic)

    其中:pStm為IStream*類型的COM接口指針,需事先在內(nèi)存中創(chuàng)建,并裝載了來自圖片文件的數(shù)據(jù)流;dwSize為指明載入圖片數(shù)據(jù)的字節(jié)數(shù),即圖片文件的大?。籉ALSE為布爾值,這里傳入FALSE很關(guān)鍵,否則對流的操作將失效;IID_IPicture為接口標識符;m_pPic為IPicture*類型的COM接口指針,即載入圖片的存放處。

    其關(guān)鍵技術(shù)是在內(nèi)存中建立圖片數(shù)據(jù)流,其實現(xiàn)的關(guān)鍵代碼如下:

    //省略錯誤處理部分

    CFile file;

    file.Open(strFileName,CFile::modeRead);

    DWORD dwSize=file.GetLength();

    //在內(nèi)存中分配堆空間

    HGLOBAL hMem=GlobalAlloc(GMEM_MOVEABLE, dwSize);

    LPVOID pDes = ::GlobalLock(hMem);

    //通過文件讀操作將圖片內(nèi)容載入堆空間:

    file.Read(pDes,dwSize);

    //在堆空間上建立圖片數(shù)據(jù)流pStm:

    IStream *pStm=NULL;

    CreateStreamOnHGlobal(hMem,TRUE,&pStm);

    通過以上代碼,IPicture*類型的控件變量m_pPic即在內(nèi)存中保存了圖片數(shù)據(jù)流,并且該數(shù)據(jù)流可以用于后續(xù)的存入數(shù)據(jù)庫操作。

    1.2 顯示圖片

    裝載了圖片數(shù)據(jù)的IPicture控件,主要功能之一是用于圖片顯示,其用到成員函數(shù)Render()。該功能比較容易實現(xiàn),本文不詳述。

    2 將BLOB字段值載入IPicture控件

    在Visual C++ 6.0開發(fā)環(huán)境下,數(shù)據(jù)庫的訪問比較常用的方法是采用微軟的MFC ODBC技術(shù)。MFC ODBC封裝了CDatabase和CRecordset類,用于建立數(shù)據(jù)庫連接和從數(shù)據(jù)庫中獲取查詢數(shù)據(jù)集或更新數(shù)據(jù)庫。其中,可以在CRecordset類型的對象中傳入SQL查詢語句,并通過列綁定和列交換就可以將數(shù)據(jù)庫字段值交換為CRecordset對象成員變量值,這里不詳述。

    雖然數(shù)據(jù)庫中的BLOB類型字段可以通過列交換技術(shù)保存在CRecordset對象的成員變量中,但CLongBinary類型的成員變量并不能用于直接存取。因此,利用IPicture控件和內(nèi)存數(shù)據(jù)交換技術(shù)可以實現(xiàn)對此二進制數(shù)據(jù)流的存取技術(shù)。首先將CLongBinary類型的二進制流數(shù)據(jù)拷貝給內(nèi)存堆空間,然后在內(nèi)存堆空間上建立IStream*類型的數(shù)據(jù)流,最后用OleLoadPicture(...)函數(shù)將數(shù)據(jù)流載入IPicture控件。其實現(xiàn)的關(guān)鍵代碼如下:

    //將二進制數(shù)據(jù)拷貝給內(nèi)存堆空間:

    //lob是CLongBinary類型的變量,對應圖像字段

    //一般通過CRecordset類的列交換技術(shù)獲得。

    LPSTR pBuff=(LPSTR)GlobalLock(lob.m_hData);

    HGLOBAL hGlobal=GlobalAlloc(GMEM_MOVEABLE,

    Lob.m_dwDataLength);

    void* pData=GlobalLock(hGlobal);

    memcpy(pData,pBuff,lob.m_dwDataLength);

    GlobalUnlock(hGlobal);

    //在內(nèi)存空間上建立IStream流

    IStream *pStream=NULL;

    CreateStreamOnHGlobal(hGlobal,TRUE,&pStream);

    //讀入數(shù)據(jù)流到IPicture控件

    OleLoadPicture(pStream,nSize,FALSE,IID_IPicture,(LPVOID*)&m_pPic)

    通過以上代碼,實現(xiàn)了將數(shù)據(jù)庫中圖片數(shù)據(jù)讀取到IPicture控件中的功能。該IPicture控件對象可用于顯示圖片內(nèi)容或?qū)D片內(nèi)容存入文件或數(shù)據(jù)庫。

    3 將IPicture控件內(nèi)容寫入數(shù)據(jù)庫

    將IPicture控件中的圖片數(shù)據(jù)存入數(shù)據(jù)庫字段中是第2節(jié)中所述的反向操作。這里,關(guān)鍵是如何獲得IPicture組件中的數(shù)據(jù)流,本文通過對IPicture接口的研究,開發(fā)了實現(xiàn)技術(shù),其主要代碼如下:

    //申請內(nèi)存空間,并創(chuàng)建IStream流,與內(nèi)存綁定

    IStream* pSrcStream=NULL;

    //m_dwImgSize變量:從文件中讀入圖像時保存的圖像大小

    HGLOBAL hMemSrc=::GlobalAlloc(GPTR,m_dwImgSize);

    BYTE *pMem=0;

    if(hMemSrc!=NULL)

    {

    pMem=(BYTE*)GlobalLock(hMemSrc);

    if(pMem!=NULL)

    {

    //在申請的內(nèi)存空間上綁定IStream型變量

    hr=::CreateStreamOnHGlobal(hMemSrc,TRUE,&pSrcStream);

    GlobalUnlock(hMemSrc);

    }

    else//出錯處理

    {

    GlobalFree(hMemSrc);

    hr=E_OUTOFMEMORY;

    }

    }

    else

    {

    hr=E_OUTOFMEMORY;

    }

    if(NULL==pSrcStream)

    return hr;

    //通過pSrcStream將IPicture圖像數(shù)據(jù)存入內(nèi)存區(qū)塊pMem;

    LONG cbSize=0;

    //SaveAsFile函數(shù)起了關(guān)鍵作用。

    hr=m_pPic->SaveAsFile(pSrcStream,FALSE,&cbSize);

    if(FAILED(hr))

    {

    pSrcStream->Release();

    pSrcStream=NULL;

    return hr;

    }

    else

    {

    //將pSrcStream指針置于數(shù)據(jù)起始位置,以便后續(xù)寫入字段操作。

    hr=pSrcStream->Commit(STGC_DEFAULT);

    LARGE_INTEGER dlibMove;

    ULARGE_INTEGER dlibNew;

    memset(&dlibMove,0,sizeof(dlibMove));

    hr=pSrcStream->Seek(dlibMove,STREAM_SEEK_SET,&dlibNew);

    }

    //利用源流pSrcStream寫入目標流(字段)

    if(pMem)

    {

    //lob是CLongBinary類型的變量,對應圖像字段

    lob.m_dwDataLength=m_dwImgSize;

    HGLOBAL hGlobal=GlobalAlloc(GPTR,m_dwImgSize);//申請存放圖像數(shù)據(jù)的空間。

    lob.m_hData = GlobalLock(hGlobal);//將該空間賦給m_hData成員;

    //向圖像字段寫入IPicture數(shù)據(jù)

    memcpy(lob.m_hData,pMem,m_dwImgSize);

    GlobalUnlock(hGlobal);

    pSrcStream->Release();

    pSrcStream=NULL;

    }

    上述代碼關(guān)鍵點為IPicture控件成員函數(shù)SaveAsFile的應用,并注意第二參數(shù)應設置為FALSE,它實現(xiàn)了提取控件中的圖像數(shù)據(jù)流并存入內(nèi)存區(qū)塊的目的。其他代碼都是圍繞此圖像數(shù)據(jù)區(qū)塊的數(shù)據(jù)交換操作,以實現(xiàn)將圖像數(shù)據(jù)存入數(shù)據(jù)庫字段的功能。4 封裝一個通用類CPictureField

    利用 C++語言面向?qū)ο蟮牧己锰匦裕O計出針對數(shù)據(jù)庫圖像字段的通用類CPictureField。該類封裝了上述介紹的主要功能,類型聲明主要如下:

    class CPictureField{

    public:

    //將IPicture圖像數(shù)據(jù)存入數(shù)據(jù)庫字段,

    //通過CRecordset接口可以獲取目標字段

    //通常是二進制數(shù)據(jù)流類型CLongBinary

    HRESULT DumpToField(CRecordset& set);

    //將IPicture圖像數(shù)據(jù)存入文件

    HRESULT DumpToFile(LPCTSTR szFileName);

    //將數(shù)據(jù)庫圖像數(shù)據(jù)載入IPicture控件

    bool LoadFromField(CRecordset& set);

    //將圖像文件內(nèi)容載入IPicture控件//同時,該函數(shù)保存了圖像大小m_dwImgSize

    bool LoadFromFile(LPCTSTR strFileName);

    ……

    protected:

    DWORD m_dwImgSize;

    ……

    //核心部件:IPicture控件指針

    IPicture* m_pPic;

    };

    CPictureField類實現(xiàn)的主要功能有:①從硬盤圖像文件中載入圖像數(shù)據(jù);②將圖像數(shù)據(jù)寫入數(shù)據(jù)庫字段;③將圖像數(shù)據(jù)寫入硬盤文件;④從數(shù)據(jù)庫字段中載入圖像數(shù)據(jù)。

    5 結(jié)論

    本文介紹了在C++編程語言環(huán)境下(基于Visual C++ 6.0版本),利用IPicture控件,結(jié)合內(nèi)存數(shù)據(jù)交換技術(shù),進行數(shù)據(jù)庫圖像字段的直接存取,解決了常規(guī)方法的數(shù)據(jù)一致性、安全性及完整性方面的問題。通過項目的實際應用,驗證了該技術(shù)思路的可行性。同時,本文給出了實現(xiàn)此類功能的核心代碼,讀者可以根據(jù)自己項目開發(fā)的實際需要,稍加修改及整合,即可應用到具體的項目實踐中。

    [1] 李閩溟,吳繼剛.Visual C++ 6.0數(shù)據(jù)庫系統(tǒng)開發(fā)實例導航[M].北京:人民郵電出版社,2002.

    Access Image Data in A Database by Using IPicture Control

    FAN Yang-hua

    (School of Software Engineering, Tongji University, Shanghai 201900, China)

    To the problem of poor consistency, security and integrity in the storage of image data in the development of database application program, an access method of the image data by using IPicture control in large database is proposed, which is based on binary large object (BLOB) field types provided by database management systems.

    technology of database access; IPicture control; image data

    1672- 6413(2015)06- 0036- 02

    2015- 01- 04;

    2015- 09- 27

    凡揚華(1976-),男,湖南郴州人,工程師,本科, 現(xiàn)從事鋼鐵產(chǎn)品工藝設計管理工作 。

    TP274

    A

    猜你喜歡
    二進制字段數(shù)據(jù)流
    圖書館中文圖書編目外包數(shù)據(jù)質(zhì)量控制分析
    用二進制解一道高中數(shù)學聯(lián)賽數(shù)論題
    汽車維修數(shù)據(jù)流基礎(chǔ)(下)
    有趣的進度
    二進制在競賽題中的應用
    一種提高TCP與UDP數(shù)據(jù)流公平性的擁塞控制機制
    基于數(shù)據(jù)流聚類的多目標跟蹤算法
    CNMARC304字段和314字段責任附注方式解析
    北醫(yī)三院 數(shù)據(jù)流疏通就診量
    無正題名文獻著錄方法評述
    金平| 祁东县| 法库县| 金山区| 封丘县| 万州区| 云安县| 湘潭市| 蒲江县| 桐梓县| 亳州市| 道真| 休宁县| 襄垣县| 特克斯县| 白城市| 浦江县| 塔城市| 平阳县| 青浦区| 陕西省| 灯塔市| 田林县| 临武县| 盐山县| 灵台县| 丰县| 沂水县| 鲁山县| 卢龙县| 镇宁| 大荔县| 邵阳县| 包头市| 平安县| 天津市| 珲春市| 松原市| 定西市| 平塘县| 合水县|