freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

基于mfc的圖片瀏覽器的設(shè)計與實(shí)現(xiàn)-畢業(yè)論文-資料下載頁

2025-11-03 15:26本頁面

【導(dǎo)讀】特色和個性的基于MFC的圖片瀏覽器。本論文對圖片瀏覽器的常用功能進(jìn)行設(shè)計開發(fā),通過本文,可以初步掌握圖形圖像編程的方法與技巧。

  

【正文】 ndowHeight) m_showY=m_nWindowHeight/。 else m_showY=0。 pFramem_bScrModeChged=FALSE。 23 } LanImage 類中的 Draw()函數(shù)定義如下: BOOL LanImage::Draw(HDC hdc,int nDx,int nDy,int nDw,int nDh, int nSx,int nSy,int nSw,int nSh,UINT uFlags)const 此函數(shù)調(diào)用 MFC 函數(shù) DrawDibDraw()來實(shí)現(xiàn)圖像的顯示,函數(shù)各參數(shù)的意義如下。 hdc:設(shè)備 DC 句柄。 nDx:圖像顯示的目標(biāo)區(qū)域左上角 X 坐標(biāo)。 nDy:圖像顯示的目標(biāo)區(qū)域左上角 Y 坐標(biāo)。 nDw:目標(biāo)區(qū)域?qū)挾取? nDh:目標(biāo)區(qū)域高度。 nSx:顯示時截取源圖像區(qū)域的左上角 X 坐標(biāo)。 nSy:顯示時截取源圖像區(qū)域的左上角 Y 坐標(biāo)。 nSw:源區(qū)域?qū)挾取? nSh:源區(qū)域高度。 uFlags:供 DrawDibDraw()函數(shù)使用的標(biāo)志變量,可忽略。 全屏瀏覽模塊 全屏瀏覽模塊是以桌面即 DesktopWindow 的布局來調(diào)整軟件窗口的布局,從而實(shí)現(xiàn)全屏顯示的。而全屏?xí)r浮動工具欄的自動隱藏,是利用計時器實(shí)現(xiàn)的。實(shí)現(xiàn)全屏瀏覽模塊的 流程圖 如 圖 8 所示 : 24 圖 8 全屏瀏覽模塊流程圖 圖像縮放模塊 圖像的縮放是由 LanImage 的 Draw()函數(shù)實(shí)現(xiàn)的,由前面的內(nèi)容可知, Draw()函數(shù)提供的參數(shù)主要有兩部分,一部分是目標(biāo)區(qū)域的位置和大小,另一部分是源圖像區(qū)域的位置和大小。因此,只要改變目標(biāo)區(qū)域的大小,也即 nDw、 nDh,即可實(shí)現(xiàn)圖像的縮放。以圖像的逐漸縮小為例,其 流程圖 如 圖 9 所示 : 自動隱藏全局工具欄 結(jié)束 創(chuàng)建新工具欄 計算圖片顯示位置 設(shè)置計時器及標(biāo)志 恢復(fù)窗體 停止全屏顯示 開始 保存全屏狀態(tài)的窗口布局 ! m_bFullScreen Y N RGB 壓縮 25 圖 9 圖像縮放模塊流程圖 上述函數(shù)中后面部分即為實(shí)現(xiàn)狀態(tài)欄信息顯示的改變。本函數(shù)中由于改變了圖像的顯示大小,故“顯示比例”一項(xiàng)需要更新,而 m_Llower_rate 即為圖像當(dāng)前的顯示比例,此變量 在 CPictViewView 類中定義。 圖像旋轉(zhuǎn)模塊 圖像旋轉(zhuǎn)的實(shí)現(xiàn)較為復(fù)雜,是本設(shè)計中的難點(diǎn)。旋轉(zhuǎn)有兩種思路,一種是像縮放一樣,借助于 LanImage::Draw()函數(shù),按照旋轉(zhuǎn)要求改變目標(biāo)區(qū)域的水平坐標(biāo)和垂直坐標(biāo),使其與源圖像的坐標(biāo)不同。但是要使整幅圖像都翻轉(zhuǎn)過來,必須對圖像的每個像素調(diào)用一次Draw()函數(shù)。這樣,如果是一幅 640 480 像素大小的圖像,旋轉(zhuǎn)一次就要調(diào)用 640 480= 307200 次的 Draw()函數(shù), Draw()函數(shù)又是調(diào)用 DrawDibDraw()實(shí)現(xiàn)的,而此函數(shù)因?yàn)樯婕暗椒浅?fù)雜的函數(shù)調(diào)用關(guān)系,并不適合進(jìn)行如此大量次數(shù)的調(diào)用,如果采用這種方法實(shí)現(xiàn)旋轉(zhuǎn),其執(zhí)行速度是讓人無法忍受的。 因此,要實(shí)現(xiàn)旋轉(zhuǎn),必須在內(nèi)存中對圖像數(shù)據(jù)的緩沖區(qū)先做好變換,然后一次性調(diào)用Draw()函數(shù)將其繪制在屏幕上。但是,在內(nèi)存中進(jìn)行像素數(shù)據(jù)的變換,關(guān)鍵之處在于:對每像素位數(shù)不同的圖像,必須使用不同的操作。例如,如果是 8 位的圖片,那么每個像素正好是一個字節(jié),變換時以字節(jié)為單位即可;如果是 32 位的圖片,則是 4 字節(jié)一個像素,那么變換時應(yīng)以 4 字節(jié)為單位;而如果是單色位圖,那么 8 個像素才構(gòu)成一個字結(jié)束 設(shè)置狀態(tài)欄顯示比例 重繪 開始 顯示比例逐漸減少 倍 顯示比例 0 Y 是否第一次顯示 N 26 節(jié),此時 就必須進(jìn)行位操作。 下面以 8 位和 32 位的圖像來說明旋轉(zhuǎn)操作的算法,而需要進(jìn)行位操作的圖像的旋轉(zhuǎn)方法在后面進(jìn)行詳細(xì)說明,這里不再贅述。 流程圖如 圖 10 所示: 圖 10 圖像旋轉(zhuǎn)模塊流程圖 圖像特效顯示 與圖像的旋轉(zhuǎn)一樣,圖像的特效顯示也有兩種實(shí)現(xiàn)思路。 借助于循環(huán)和對 LanImage::Draw()函數(shù)的參數(shù)進(jìn)行變換,以達(dá)到特效顯示的效果。 先在內(nèi)存中將特效的一幀變換好,然后一次性顯示整幅圖像,再進(jìn)行下一幀的變換、顯示,如此循環(huán)直到將所有的 幀顯示完畢。 很明顯,直接對內(nèi)存數(shù)據(jù)操作實(shí)現(xiàn)特效的(簡稱為內(nèi)存特效)效率要比借助于 Draw()函數(shù)的變換高。但是,由于特效所需幀數(shù)并不太多,因此使用 Draw()函數(shù)的方法也是可行的,并且是現(xiàn)在常用的基本特效實(shí)現(xiàn)方法之一;內(nèi)存特效的實(shí)現(xiàn)難度較大。因此,這里先介紹借助于 Draw()函數(shù)的實(shí)現(xiàn)方法,在后面將對內(nèi)存特效進(jìn)行較詳細(xì)的介紹。 以馬賽克效果為例?;静襟E如下。 步驟 1: 根據(jù)圖像大小選擇合適的馬賽克塊的大小。 結(jié)束 順時針翻轉(zhuǎn) 是否為 8 位圖像 Y 寬度 是否為 32位 翻轉(zhuǎn) 高度 N N Y Y 開始 27 步驟 2: 計算出此圖像水平和垂直方向可以分的塊數(shù)。 步驟 3: 假設(shè)水平方向可以分為 i 塊,垂直方向可以分 為 j 塊,那么創(chuàng)建一個 i j 大小的整型數(shù)組 LanArrow[i][j],初始化為 0。 步驟 4: 利用隨機(jī)函數(shù)任意選出一塊,查看對應(yīng)的 LanArrow 數(shù)組元素的值,如果為 0,則顯示該塊,然后將 LanArrow 對應(yīng)元素置為 1;如果對應(yīng)的 LanArrow 中的值已為 1,則繼續(xù)隨機(jī)選擇,直到找出一個 LanArrow 中值為 0 的塊。 步驟 5: 計數(shù),如果循環(huán)次數(shù)未達(dá)到 i j,返回步驟 4 繼續(xù)執(zhí)行,否則結(jié)束。 其中,由于 LanArrow 的大小事先是無法確定的,因此使用了動態(tài)二維數(shù)組。 馬賽克特效顯示模塊算法流程圖 如 圖 11 所示 : 圖 11 馬賽克特效顯示模塊流程圖 計算水平和垂直防線可分的塊數(shù) 開始 選擇合適的馬賽克大小 二維數(shù)組 ==0 尋找二維數(shù)組標(biāo)記為 0 的塊 Y N 創(chuàng)建二維數(shù)組 ==0 置二維數(shù)組元素為 1 計數(shù) i*j 結(jié)束 N Y 28 本設(shè)計中借助于 Draw()函數(shù)實(shí)現(xiàn)的特效還有百葉窗、從上往下、從下往上、從左往右、從右往左、左上進(jìn)入、左下進(jìn)入、右上進(jìn)入、右下進(jìn)入等,在此不再贅述。 4 系統(tǒng)的關(guān)鍵技術(shù)及難點(diǎn) 在兩個多月的學(xué)習(xí)與工作中,我完成了一個完整的基于 MFC 的圖片瀏覽器的設(shè)計。在設(shè)計過程中,我遇到了許多的技術(shù)問題,下面介紹該系統(tǒng)設(shè)計與實(shí)現(xiàn)的關(guān)鍵技術(shù)和技術(shù)難點(diǎn)。 資源的分配和釋放 由于 Visual C++中內(nèi)存資源的分配和釋放均由程 序員控制,而本程序多處在內(nèi)存中開辟緩沖區(qū),因此在本設(shè)計的實(shí)現(xiàn)過程中,對內(nèi)存的管理尤為重要。 比如,在打開一張新圖片時,就要對上一張圖片的緩沖區(qū)進(jìn)行釋放,否則會造成內(nèi)存的泄漏。但是由于 JPEG 和 GIF 調(diào)用了第三方的讀寫庫,其使用的內(nèi)存緩沖區(qū)格式與LanImage 類中使用的不同,因此,在進(jìn)行緩沖區(qū)的釋放時,首先要判斷上一張圖片是何種格式,即是否使用了第三方的讀寫庫,如果使用了,則應(yīng)采取不同的資源釋放方式。 本設(shè)計是通過在 LanImage 類中加入 Bool 型變量 m_bReadWithLibSupport 來判斷是否使 用了 JPEG 和 GIF 讀寫庫的。例如,在 OnFileOpen()函數(shù)中,資源的釋放代碼如下: if () { //在 LanImage::LoadImage()中 m_pJpeg=new CJpeg()分配的空間 if ( !=NULL) //上次打開的是 JPEG格式 { CJpeg * pTempJpeg=。 =NULL。 if(!) //進(jìn)行過變換 delete [] 。 =NULL。 =NULL。 delete pTempJpeg。 } if( !=NULL) //上次打開的是 GIF格式 { CGif * pTempGif=。 =NULL。 29 if(!) //進(jìn)行過變換 delete [] 。 =NULL。 =NULL。 delete pTempGif。 } } else ()。 使用 JPEG 和 GIF 讀寫庫時緩沖區(qū)格式的轉(zhuǎn)換 此前已經(jīng)提到使用 JPEG 和 GIF 讀寫庫時,其解碼后的數(shù)據(jù)緩沖區(qū)格式是不同的,而圖像的顯示都是通 過 LanImage::Draw()函數(shù)實(shí)現(xiàn)的。 Draw()函數(shù)只能讀取 LanImage 類中m_pImage 指向的緩沖區(qū)。因此,在圖像打開時需要進(jìn)行緩沖區(qū)的轉(zhuǎn)換。 另外,如果打開的是 BMP、 TGA、 PCX 格式的圖像,而用戶選擇保存為 JPEG 或 GIF圖像,那么又要將 m_pImage 指向的緩沖區(qū)轉(zhuǎn)換為 JPEG 和 GIF 讀寫庫所使用的緩沖區(qū)。 其具體的實(shí)現(xiàn)如下。 ( 1)打開圖像時的緩沖區(qū)轉(zhuǎn)換 JPEG 和 GIF 讀寫庫中使用一個 CDib 類保存圖像的數(shù)據(jù),即是以 DIB 格式存儲的,而此類中提供了獲得圖像數(shù)據(jù)區(qū)指針及其圖像屬性 的方法,因此,利用這些接口,即可將緩沖區(qū)轉(zhuǎn)換為 LanImage 中使用的類型。以 JPEG 為例,代碼如下( GIF 與 JPEG 類似): if( (_tcsicmp(pszExt,.jpg)==0)|| (_tcsicmp(pszExt,.jpeg)==0)) { m_bReadWithLibSupport=TRUE。 m_pJpeg=new CJpeg()。 bRet=m_pJpegLoad(pszFileName)。 //bRet為 Bool類型,標(biāo)志是否載入成功 if(!bRet) { AfxMessageBox(載入 JPEG文件時發(fā)生錯誤 !)。 return FALSE。 } CDib *pDib=m_pJpegGetDib()。 //獲取 CDib指針 m_pImage=pDibGetBitsPtr()。 //獲取 DIB數(shù)據(jù)區(qū)指針 m_nWidth=pDibGetWidth()。 m_nHeight=pDibGetHeight()。 30 m_nBitCount=pDibGetBitCount()。 m_nImage=m_nHeight*(pDibGetWidthBytes())。 m_nPitch=pDibGetWidthBytes()。 m_nPalette=0。 } ( 2)保存圖像時的數(shù)據(jù)區(qū)轉(zhuǎn)換 如果打開的是非 JPEG 和 GIF 圖像,而要保存成這兩種格式,那么為了使用讀寫庫提供的編碼函數(shù),就必須將 m_pImage 指向的數(shù)據(jù)及圖像的各種屬性創(chuàng)建為 CDib 對象。具體實(shí)現(xiàn)代碼如下: BOOL LanImage::CreateDib(CDib **pDib) { BITMAPINFOHEADER bmiHeader。 HDIB hDIB。 =sizeof(BITMAPINFOHEADER)。 =m_nWidth。 =m_nHeight。 =1。 =m_nBitCount。 =BI_RGB。 =m_nImage。 =0。 =0。 //如果打開的圖片 BitCount8則無調(diào)色板 if(m_nBitCount8) =0。 else =m_nPalette。 =0。 //分新的 DIB分配空間,并將圖像數(shù)據(jù)復(fù)制到此空間中 DWORD dwHeaderSize=sizeof(BITMAPINFOHEADER)。 DWORD dwPaletteSize=sizeof(RGBQUAD)*m_nPalette。 DWORD dwBitsSize=WIDTHBYTES(m_nWidth*m_nBitCount)* m_nHeight。 if(m_nBitCount8) hDIB=GlobalAlloc(GHND, dwHeaderSize+dwBitsSize)。 else hDIB=GlobalAlloc(GHND, dwHeaderSize+dwPaletteSize+dwBitsSize)。 if (hDIB==NULL) return FALSE。 31 LPBYTE lpDIB=(LPBYTE)GlobalLock(hDIB)。 memcpy(lpDIB, (LPBYTE)amp。bmiHeader, dwHeaderSize)。 if(m_nBitCount=8) //寫調(diào)色板 memcpy(lpDIB+dwHeaderSize,m_pPal,dwPaletteSize)。 //寫圖像數(shù)據(jù) memcpy(FindDIBBits((LPBYTE)lpDIB), m_pImage, dwBitsSize)。 *pDib=new CDib()。 (*pDib)Attach(hDIB)。 GlobalUnlock(hDIB)。 return TRUE。 } 實(shí)現(xiàn)旋轉(zhuǎn)時對內(nèi)存的
點(diǎn)擊復(fù)制文檔內(nèi)容
醫(yī)療健康相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1