亚洲免费乱码视频,日韩 欧美 国产 动漫 一区,97在线观看免费视频播国产,中文字幕亚洲图片

      1. <legend id="ppnor"></legend>

      2. 
        
        <sup id="ppnor"><input id="ppnor"></input></sup>
        <s id="ppnor"></s>

        在VC下顯示JPEG、GIF格式圖像的一種簡便方法

        字號:

        一、 引言
            JPEG圖像壓縮標準隨然是一種有損圖像壓縮標準,但由于人眼視覺的不敏感,經(jīng)壓縮后的畫質(zhì)基本沒有發(fā)生變化,很快便以較高的壓縮率得到了廣泛的認可。GIF格式雖然僅支持256色但它對于顏色較少的圖像有著很高的壓縮率,甚至超過JPEG標準,也得到了廣泛的認同。但作為眾多程序員的一個重要的開發(fā)工具--Microsoft Visual C++ 6.0的MFC庫卻僅對沒有經(jīng)過任何壓縮的BMP位圖文件有著良好的支持,可以讀取、顯示、存儲甚至在內(nèi)存中創(chuàng)建一塊內(nèi)存位圖。由于BMP格式的圖像沒有經(jīng)過任何的壓縮,不論是作為程序的外部文件,還是作為程序的內(nèi)部資源都要占據(jù)大量的空間,尤其是后者會大大增加可執(zhí)行文件的長度??梢钥闯?,如果能用經(jīng)過壓縮、具有較好的壓縮率的JPEG或GIF格式的圖像來取代BMP文件在VC中的應(yīng)用,無疑還是很有吸引力的。
             二、 設(shè)計思路
            雖然有一些操作、處理JPEG、GIF等其他格式圖像的Active X控件,但總的來說使用起來并不太方便,筆者經(jīng)過實驗摸索,總結(jié)出了一種借助于COM接口的OLE方法來實現(xiàn)上述功能的一種簡便方法,現(xiàn)介紹如下以饗廣大讀者:
             下面我們要使用IPicture 的COM接口,有必要對該圖像接口做些了解:該接口主要管理圖像對象及其屬性,圖像對象為位圖、圖標和圖元等提供一種與語言無關(guān)的抽象。和標準的字體對象一樣,系統(tǒng)也提供了對圖像對象的標準實現(xiàn)。其主要的接口是IPicture和IPictureDisp,后者是由IDispatch接口派生以便通過自動化對圖像的屬性進行訪問。圖像對象也支持外部接口IPropertyNotifySink,以便用戶能在圖像屬性發(fā)生改變時作出決定。圖像對象也支持IPersistStream接口,所以它能從一個IStream接口的實例對象保存、裝載自己,而IStream接口也支持對流對象的數(shù)據(jù)讀寫。
            我們可以用函數(shù)OleLoadPicture從包含有圖像數(shù)據(jù)的流中裝載圖像。該函數(shù)簡化了基于流的圖像對象的創(chuàng)建過程,可以創(chuàng)建一個新的圖像對象并且用流中的內(nèi)容對它進行初始化。其函數(shù)原型為:
             STDAPI OleLoadPicture( IStream * pStream, //指向包含有圖像數(shù)據(jù)的流的指針LONG lSize, //從流中讀取的字節(jié)數(shù)BOOL fRunmode, //圖像屬性對應(yīng)的初值REFIID riid, //涉及到的接口標識,描述要返回的接口指針的類型VOID ppvObj // 在rrid中用到的接口指針變量的地址);
             三、 具體的實現(xiàn)
            在顯示圖像之前,首先要獲取到圖像文件的存放路徑,這里采用標準的文件打開對話框來選取圖像文件,文件名存放在CString型的變量m_sPath中:
             CFileDialog dlg(TRUE,“jpg“,“*.jpg“,
             OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
             “JPEG文件(*.jpg)|*.jpg|GIF文件(*.gif)|*.gif||“,NULL);
             if(dlg.DoModal()==IDOK)
             {
             m_sPath=dlg.GetPathName();
             Invalidate();
             }
             為簡單計,圖形顯示的代碼直接在視類中的OnDraw中編寫,首先打開文件并判斷文件的可用性,并把文件內(nèi)容放到流接口IStream的對象pStm中:
             IStream *pStm;
             CFileStatus fstatus;
             CFile file;
             LONG cb;
             ……
             if (file.Open(m_Path,CFile::modeRead)&&file.GetStatus(m_Path,fstatus)&& ((cb = fstatus.m_size) != -1))
             {
             HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb);
             LPVOID pvData = NULL;
             if (hGlobal != NULL)
             {
             if ((pvData = GlobalLock(hGlobal)) != NULL)
             {
             file.ReadHuge(pvData, cb);
             GlobalUnlock(hGlobal);
             CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);
             }
             }
             }
            然后,就直接調(diào)用OleLoadPicture函數(shù)從流中裝載圖像:
             IPicture *pPic;
             ……
             OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&pPic));
               由于該函數(shù)有時會導(dǎo)致失敗,所以應(yīng)當用SUCCEEDED宏來做一些適當?shù)谋Wo工作,只有在數(shù)據(jù)裝載成功的前提下才能繼續(xù)下面的圖像顯示工作:
             if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&pPic)))
             {
             OLE_XSIZE_HIMETRIC hmWidth;
             OLE_YSIZE_HIMETRIC hmHeight;
             pPic->get_Width(&hmWidth);
             pPic->get_Height(&hmHeight);
             double fX,fY;
             ……
             fX = (double)pDC->GetDeviceCaps(HORZRES)*(double)hmWidth/((double)pDC->GetDeviceCaps(HORZSIZE)*100.0);
             fY = (double)pDC->GetDeviceCaps(VERTRES)*(double)hmHeight/((double)pDC->GetDeviceCaps(VERTSIZE)*100.0);
             if(FAILED(pPic->Render(*pDC,0,0,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeight,NULL)))
             AfxMessageBox(“渲染圖像失敗!“);
             pPic->Release();
             }
             else
             AfxMessageBox(“從流中裝載圖像失敗!“);
            其中,顯示工作主要是由IPicture接口對象的Render函數(shù)來完成的,該函數(shù)主要用來將圖片的指定部分畫到指定的設(shè)備環(huán)境的指定位置。原型如下:
             HRESULT Render( HDC hdc, //渲染圖像用的設(shè)備環(huán)境句柄
             long x, //在hdc上的水平坐標
             long y, //在hdc上的垂直坐標
             long cx, //圖像寬度
             long cy, //圖像高度
             OLE_XPOS_HIMETRIC xSrc, //在源圖像上的水平偏移
             OLE_YPOS_HIMETRIC ySrc, //在源圖像上的垂直偏移
             OLE_XSIZE_HIMETRIC cxSrc,//在源圖像上水平拷貝的數(shù)量
             OLE_YSIZE_HIMETRIC cySrc,//在源圖像上垂直拷貝的數(shù)量
             LPCRECT prcWBounds //指向目標圖元設(shè)備環(huán)境句柄的指針);
            小結(jié):到此為止,通過上述代碼已經(jīng)能夠在程序的客戶區(qū)內(nèi)顯示JPEG、GIF等標準的圖像了,但對于有多幀圖片(即有動畫)的GIF格式的圖像,目前還只能顯示第一幀,如要完整的顯示GIF 動畫的全過程,還需要外部Active X控件的支持。