久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

| 天極Yesky - 全球中文IT第一門(mén)戶 - 軟件 - VC數(shù)字圖像處理編程講座之三

 傷心莫哭 2010-11-08
一,、 BMP位圖操作

  首先我們回顧一下上講中的重要信息:BMP位圖包括位圖文件頭結(jié)構(gòu)BITMAPFILEHEADER、位圖信息頭結(jié)構(gòu)BITMAPINFOHEADER,、位圖顏色表RGBQUAD和位圖像素?cái)?shù)據(jù)四部分,。處理位圖時(shí)要根據(jù)文件的這些結(jié)構(gòu)得到位圖文件大小、位圖的寬,、高,、實(shí)現(xiàn)調(diào)色板、得到位圖像素值等等,。這里要注意的一點(diǎn)是在BMP位圖中,,位圖的每行像素值要填充到一個(gè)四字節(jié)邊界,即位圖每行所占的存儲(chǔ)長(zhǎng)度為四字節(jié)的倍數(shù),,不足時(shí)將多余位用0填充,。

  有了上述知識(shí),可以開(kāi)始編寫(xiě)圖像處理的程序了,關(guān)于在VC的開(kāi)發(fā)平臺(tái)上如何開(kāi)發(fā)程序的問(wèn)題這里不再贅述,,筆者假定讀者都具有一定的VC開(kāi)發(fā)經(jīng)驗(yàn),。在開(kāi)發(fā)該圖像處理程序的過(guò)程中,筆者沒(méi)有采用面向?qū)ο蟮姆椒?,雖然面向?qū)ο蟮姆椒梢詫?shù)據(jù)封裝起來(lái),,保護(hù)類(lèi)中的數(shù)據(jù)不受外界的干擾,提高數(shù)據(jù)的安全性,,但是這種安全性是以降低程序的執(zhí)行效率為代價(jià)的,,為此,我們充分利用了程序的文檔視圖結(jié)構(gòu),,在程序中直接使用了一些API函數(shù)來(lái)操作圖像,。在微軟的MSDN中有一個(gè)名為Diblook的例子,該例子演示了如何操作Dib位圖,,有興趣的讀者可以參考一下,,相信一定會(huì)有所收獲。

  啟動(dòng)Visual C++,,生成一個(gè)名為Dib的多文檔程序,,將CDibView類(lèi)的基類(lèi)設(shè)為CscrollView類(lèi),這樣作的目的是為了在顯示位圖時(shí)支持滾動(dòng)條,,另外在處理圖像應(yīng)用程序的文檔類(lèi)(CDibDoc.h)中聲明如下宏及公有變量:

#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)//計(jì)算圖像每行象素所占的字節(jié)數(shù)目,;
HANDLE m_hDIB;//存放位圖數(shù)據(jù)的句柄;
CPalette* m_palDIB;//指向調(diào)色板Cpalette類(lèi)的指針,;
CSize m_sizeDoc;//初始化視圖的尺寸,,該尺寸為位圖的尺寸;

  最后將程序的字符串表中的字符串資源IDR_DibTYPE修改為:“\nDib\nDib\nDib Files(*.bmp;*.dib)\n.bmp\nDib.Document\nDib Document”,。這樣作的目的是為了在程序文件對(duì)話框中可以選擇BMP或DIB格式的位圖文件,。

  1、 讀取灰度BMP位圖

  可以根據(jù)BMP位圖文件的結(jié)構(gòu),,操作BMP位圖文件并讀入圖像數(shù)據(jù),,為此我們充分利用了VC的文檔視圖結(jié)構(gòu),重載了文擋類(lèi)的OnOpenDocument()函數(shù),,這樣用戶就可以在自動(dòng)生成程序的打開(kāi)文件對(duì)話框中選擇所要打開(kāi)的位圖文件,,然后程序?qū)⒆詣?dòng)調(diào)用該函數(shù)執(zhí)行讀取數(shù)據(jù)的操作。該函數(shù)的實(shí)現(xiàn)代碼如下所示:

BOOL CDibDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
LOGPALETTE *pPal;//定義邏輯調(diào)色板指針,;
pPal=new LOGPALETTE;//初始化該指針,;
CFile file;
CFileException fe;
if (!file.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite, &fe))
{//以“讀”的方式打開(kāi)文件;
AfxMessageBox("圖像文件打不開(kāi),!");
return FALSE;
}
DeleteContents();//刪除文擋,;
BeginWaitCursor();
BITMAPFILEHEADER bmfHeader;//定義位圖文件頭結(jié)構(gòu),;
LPBITMAPINFO lpbmi;
DWORD dwBitsSize;
HANDLE hDIB;
LPSTR pDIB;//指向位圖數(shù)據(jù)的指針;
BITMAPINFOHEADER *bmhdr;//指向位圖信息頭結(jié)構(gòu)的指針
dwBitsSize = file.GetLength();//得到文件長(zhǎng)度
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) !=sizeof(bmfHeader))
return FALSE;//讀取位圖文件的文件頭結(jié)構(gòu)信息,;
if (bmfHeader.bfType != 0x4d42) //檢查該文件是否為BMP格式的文件,;
return FALSE;
hDIB=(HANDLE) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
//為讀取圖像文件數(shù)據(jù)申請(qǐng)緩沖區(qū)
if (hDIB == 0)
{
return FALSE;
}
pDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);
//得到申請(qǐng)的緩沖區(qū)的指針;
if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
dwBitsSize - sizeof(BITMAPFILEHEADER) )
{
::GlobalUnlock((HGLOBAL)hDIB);
hDIB=NULL;
return FALSE;
}//此時(shí)pDIB數(shù)據(jù)塊中讀取的數(shù)據(jù)包括位圖頭信息,、位圖顏色表,、圖像像素的灰度值;
bmhdr=(BITMAPINFOHEADER*)pDIB;//為指向位圖信息頭結(jié)構(gòu)的指針賦值,;
::GlobalUnlock((HGLOBAL)hDIB);
if ((*bmhdr).biBitCount!=8)//驗(yàn)證是否為8bit位圖
{
AfxMessageBox("該文件不是灰度位圖格式,!");
return FALSE;
}
m_hDIB=hDIB;//將內(nèi)部變量數(shù)據(jù)賦于全局變量;
//下面是記錄位圖的尺寸,;
m_sizeDoc.x=bmhdr->biWidth;
m_sizeDoc.y=bmhdr->biHeight;
//下面是根據(jù)顏色表生成調(diào)色板,;
m_palDIB=new Cpalette;
pPal->palVersion=0x300;//填充邏輯顏色表
pPal->palNumEntries=256;
lpbmi=(LPBITMAPINFO)bmhdr;
for(int i=0;i<256;i++)
{//每個(gè)顏色表項(xiàng)的R,、G,、B值相等,并且各個(gè)值從“0”到“255”序列展開(kāi),;
Pal->palPalentry[i].peRed=lpbmi->bmiColors[i].rgbRed;
pPal->palPalentry[i].peGreen=lpbmi->bmiColors[i].rgbGreen;
pPal->palPalentry[i].peBlue= lpbmi->bmiColors[i].rgbBlue;;
pPal->palPalentry[i].peFlags=0;
}
m_palDIB->CreatePalette(pPal);
//根據(jù)讀入的數(shù)據(jù)得到位圖的寬,、高、顏色表;
if(pPal)
delete pPal;
EndWaitCursor();
SetPathName(lpszPathName);//設(shè)置存儲(chǔ)路徑
SetModifiedFlag(FALSE); // 設(shè)置文件修改標(biāo)志為FALSE
return TRUE;
}

  上面的方法是通過(guò)CFile類(lèi)對(duì)象的操作來(lái)讀取位圖文件的,,它需要分析位圖中的文件頭信息,,從而確定需要讀取的圖像長(zhǎng)度。這種方法相對(duì)來(lái)說(shuō)有些繁瑣,,其實(shí)還可以以一種相對(duì)簡(jiǎn)單的方法讀取位圖數(shù)據(jù),,首先在程序的資源中定義DIB類(lèi)型資源,然后添加位圖到該類(lèi)型中,,將圖像數(shù)據(jù)以資源的形式讀取出來(lái),,這時(shí)候就可以根據(jù)所獲取的數(shù)據(jù)中的位圖信息結(jié)構(gòu)來(lái)獲取、顯示圖像數(shù)據(jù)了,。下面的函數(shù)實(shí)現(xiàn)了以資源形式裝載圖像文件數(shù)據(jù),,該函數(shù)的實(shí)現(xiàn)代碼如下所示:

/////////////////////////////////////////////////////////////////
HANDLE LoadDIB(UINT uIDS, LPCSTR lpszDibType)
{
LPCSTR lpszDibRes =MAKEINTRESOURCE(uIDS);//根據(jù)資源標(biāo)志符確定資源的名字;
HINSTANCE hInst=AfxGetInstanceHandle();//得到應(yīng)用程序的句柄,;
HRSRC hRes=::FindResource(hInst,lpszDibRes, lpszDibType);//獲取資源的句柄,,這里lpszDibType為資源的名字“DIB”;
If(hRes==NULL)
return NULL
HGLOBAL hData=::LoadResource(hInst, hRes);//轉(zhuǎn)載資源數(shù)據(jù)并返回該句柄;
return hData;
}

  2,、 灰度位圖數(shù)據(jù)的存儲(chǔ)

  為了將圖像處理后所得到的像素值保存起來(lái),,我們重載了文檔類(lèi)的OnSaveDocument()函數(shù),這樣用戶在點(diǎn)擊Save或SaveAs子菜單后程序自動(dòng)調(diào)用該函數(shù),,實(shí)現(xiàn)圖像數(shù)據(jù)的存儲(chǔ),。該函數(shù)的具體實(shí)現(xiàn)如下:

///////////////////////////////////////////////////////////////////
BOOL CDibDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
CFile file;
CFileException fe;
BITMAPFILEHEADER bmfHdr; // 位圖文件頭結(jié)構(gòu);
LPBITMAPINFOHEADER lpBI;//指向位圖頭信息結(jié)構(gòu)的指針;
DWORD dwDIBSize;,;
if (!file.Open(lpszPathName, CFile::modeCreate |CFile::modeReadWrite | CFile::shareExclusive, &fe))
{
AfxMessageBox("文件打不開(kāi)"),;
return FALSE;
}//以讀寫(xiě)的方式打開(kāi)文件;
BOOL bSuccess = FALSE;
BeginWaitCursor();
lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) m_hDIB);
if (lpBI == NULL)
return FALSE;
dwDIBSize = *(LPDWORD)lpBI + 256*sizeof(RGBQUAD);
//圖像的文件信息所占用的字節(jié)數(shù),;
DWORD dwBmBitsSize;//BMP文件中位圖的像素所占的字節(jié)數(shù)
dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))
*lpBI->biHeight;// 存儲(chǔ)時(shí)位圖所有像素所占的總字節(jié)數(shù)
dwDIBSize += dwBmBitsSize; //BMP文件除文件信息結(jié)構(gòu)外的所有數(shù)據(jù)占用的總字節(jié)數(shù),;
lpBI->biSizeImage = dwBmBitsSize; // 位圖所有像素所占的總字節(jié)數(shù)
//以下五句為文件頭結(jié)構(gòu)填充值
bmfHdr.bfType =0x4d42; // 文件為"BMP"類(lèi)型
bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);//文件總長(zhǎng)度
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
+ 256*sizeof(RGBQUAD);
//位圖數(shù)據(jù)距離文件頭的偏移量;
file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));//向文件中寫(xiě)文件頭信息,;
file.WriteHuge(lpBI, dwDIBSize);
//將位圖信息(信息頭結(jié)構(gòu),、顏色表、像素?cái)?shù)據(jù))寫(xiě)入文件,;
::GlobalUnlock((HGLOBAL) m_hDIB);
EndWaitCursor(),;
SetModifiedFlag(FALSE); // 將文檔設(shè)為“干凈”標(biāo)志,,表示此后文檔不需要存盤(pán)提示,;
return TRUE;
}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多