国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

VC下顯示JPEG、GIF圖像的簡便方法

2019-11-17 05:19:21
字體:
供稿:網(wǎng)友
摘要:本文講述了在Visual C++ 6.0下顯示JPEG、GIF等格式標(biāo)準(zhǔn)的圖像的一種實(shí)現(xiàn)起來比較簡便的方法,對(duì)實(shí)現(xiàn)過程作有具體的說明。

  要害字:圖像、JPEG、GIF、Microsoft Visual C++ 6.0

  一、 引言

  JPEG圖像壓縮標(biāo)準(zhǔn)隨然是一種有損圖像壓縮標(biāo)準(zhǔn),但由于人眼視覺的不敏感,經(jīng)壓縮后的畫質(zhì)基本沒有發(fā)生變化,很快便以較高的壓縮率得到了廣泛的認(rèn)可。GIF格式雖然僅支持256色但它對(duì)于顏色較少的圖像有著很高的壓縮率,甚至超過JPEG標(biāo)準(zhǔn),也得到了廣泛的認(rèn)同。但作為眾多程序員的一個(gè)重要的開發(fā)工具--Microsoft Visual C++ 6.0的MFC庫卻僅對(duì)沒有經(jīng)過任何壓縮的BMP位圖文件有著良好的支持,可以讀取、顯示、存儲(chǔ)甚至在內(nèi)存中創(chuàng)建一塊內(nèi)存位圖。由于BMP格式的圖像沒有經(jīng)過任何的壓縮,不論是作為程序的外部文件,還是作為程序的內(nèi)部資源都要占據(jù)大量的空間,尤其是后者會(huì)大大增加可執(zhí)行文件的長度。可以看出,假如能用經(jīng)過壓縮、具有較好的壓縮率的JPEG或GIF格式的圖像來取代BMP文件在VC中的應(yīng)用,無疑還是很有吸引力的。

  二、 設(shè)計(jì)思路

  雖然有一些操作、處理JPEG、GIF等其他格式圖像的Active X控件,但總的來說使用起來并不太方便,筆者經(jīng)過實(shí)驗(yàn)摸索,總結(jié)出了一種借助于COM接口的OLE方法來實(shí)現(xiàn)上述功能的一種簡便方法,現(xiàn)介紹如下以饗廣大讀者:

  下面我們要使用ipicture 的COM接口,有必要對(duì)該圖像接口做些了解:該接口主要治理圖像對(duì)象及其屬性,圖像對(duì)象為 位圖、圖標(biāo)和圖元等提供一種與語言無關(guān)的抽象。和標(biāo)準(zhǔn)的字體對(duì)象一樣,系統(tǒng)也提供了對(duì)圖像對(duì)象的標(biāo)準(zhǔn)實(shí)現(xiàn)。其主要的接口是IPicture和IPictureDisp,后者是由IDispatch接口派生以便通過自動(dòng)化對(duì)圖像的屬性進(jìn)行訪問。圖像對(duì)象也支持外部接口IPRopertyNotifySink,以便用戶能在圖像屬性發(fā)生改變時(shí)作出決定。圖像對(duì)象也支持IPersistStream接口,所以它能從一個(gè)IStream接口的實(shí)例對(duì)象保存、裝載自己,而IStream接口也支持對(duì)流對(duì)象的數(shù)據(jù)讀寫。

  我們可以用函數(shù)OleLoadPicture從包含有圖像數(shù)據(jù)的流中裝載圖像。該函數(shù)簡化了基于流的圖像對(duì)象的創(chuàng)建過程,可以創(chuàng)建一個(gè)新的圖像對(duì)象并且用流中的內(nèi)容對(duì)它進(jìn)行初始化。其函數(shù)原型為:

STDAPI OleLoadPicture( IStream * pStream, //指向包含有圖像數(shù)據(jù)的流的指針
LONG lSize, //從流中讀取的字節(jié)數(shù)
BOOL fRunmode, //圖像屬性對(duì)應(yīng)的初值
REFIID riid, //涉及到的接口標(biāo)識(shí),描述要返回的接口指針的類型
VOID ppvObj // 在rrid中用到的接口指針變量的地址) ;
  三、 具體的實(shí)現(xiàn)

  在顯示圖像之前,首先要獲取到圖像文件的存放路徑,這里采用標(biāo)準(zhǔn)的文件打開對(duì)話框來選取圖像文件,文件名存放在CString 型的變量m_sPath中:

CFileDialog dlg(TRUE,"jpg","*.jpg",
OFN_HIDEREADONLYOFN_OVERWRITEPROMPT,
"JPEG文件(*.jpg)*.jpgGIF文件(*.gif)*.gif",NULL);
if(dlg.DoModal()==IDOK)
{
 m_sPath=dlg.GetPathName();
 Invalidate();
}
  為簡單計(jì),圖形顯示的代碼直接在視類中的OnDraw中編寫,首先打開文件并判定文件的可用性,并把文件內(nèi)容放到流接口IStream的對(duì)象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ù)有時(shí)會(huì)導(dǎo)致失敗,所以應(yīng)當(dāng)用SUCCEEDED宏來做一些適當(dāng)?shù)谋Wo(hù)工作,只有在數(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接口對(duì)象的Render函數(shù)來完成的,該函數(shù)主要用來將圖片的指定部分畫到指定的設(shè)備環(huán)境的指定位置。原型如下:


HRESULT Render( HDC hdc, //渲染圖像用的設(shè)備環(huán)境句柄
long x, //在hdc上的水平坐標(biāo)
long y, //在hdc上的垂直坐標(biāo)
long cx, //圖像寬度
long cy, //圖像高度
OLE_XPOS_HIMETRIC xSrc, //在源圖像上的水平偏移
OLE_YPOS_HIMETRIC ySrc, //在源圖像上的垂直偏移
OLE_XSIZE_HIMETRIC cxSrc,//在源圖像上水平拷貝的數(shù)量
OLE_YSIZE_HIMETRIC cySrc,//在源圖像上垂直拷貝的數(shù)量
LPCRECT prcWBounds //指向目標(biāo)圖元設(shè)備環(huán)境句柄的指針);
  小結(jié):

  到此為止,通過上述代碼已經(jīng)能夠在程序的客戶區(qū)內(nèi)顯示JPEG、GIF等標(biāo)準(zhǔn)的圖像了,但對(duì)于有多幀圖片(即有動(dòng)畫)的GIF格式的圖像,目前還只能顯示第一幀,如要完整的顯示GIF 動(dòng)畫的全過程,還需要外部Active X控件的支持。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 凤凰县| 车致| 宾川县| 邳州市| 崇礼县| 望奎县| 巴林右旗| 聂拉木县| 六枝特区| 聂拉木县| 汕头市| 文水县| 乡城县| 永春县| 沂源县| 崇左市| 台湾省| 呼玛县| 庆安县| 都匀市| 长武县| 桃园市| 南川市| 项城市| 仙居县| 正蓝旗| 凉城县| 保靖县| 溧阳市| 丽江市| 十堰市| 陇南市| 化州市| 商都县| 信宜市| 金川县| 循化| 石楼县| 新民市| 格尔木市| 阿图什市|