国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
| 天極Yesky - 全球中文IT第一門戶 - 軟件 - VC數(shù)字圖像處理編程講座之三
一、 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ǔ)長度為四字節(jié)的倍數(shù),不足時(shí)將多余位用0填充。

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

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

#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)//計(jì)算圖像每行象素所占的字節(jié)數(shù)目;
HANDLE m_hDIB;//存放位圖數(shù)據(jù)的句柄;
CPalette* m_palDIB;//指向調(diào)色板Cpalette類的指針;
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),重載了文擋類的OnOpenDocument()函數(shù),這樣用戶就可以在自動(dòng)生成程序的打開文件對(duì)話框中選擇所要打開的位圖文件,然后程序?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))
{//以“讀”的方式打開文件;
AfxMessageBox("圖像文件打不開!");
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();//得到文件長度
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”序列展開;
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;
}

  上面的方法是通過CFile類對(duì)象的操作來讀取位圖文件的,它需要分析位圖中的文件頭信息,從而確定需要讀取的圖像長度。這種方法相對(duì)來說有些繁瑣,其實(shí)還可以以一種相對(duì)簡單的方法讀取位圖數(shù)據(jù),首先在程序的資源中定義DIB類型資源,然后添加位圖到該類型中,將圖像數(shù)據(jù)以資源的形式讀取出來,這時(shí)候就可以根據(jù)所獲取的數(shù)據(jù)中的位圖信息結(jié)構(gòu)來獲取、顯示圖像數(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ǔ)

  為了將圖像處理后所得到的像素值保存起來,我們重載了文檔類的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("文件打不開");
return FALSE;
}//以讀寫的方式打開文件;
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"類型
bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);//文件總長度
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
+ 256*sizeof(RGBQUAD);
//位圖數(shù)據(jù)距離文件頭的偏移量;
file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));//向文件中寫文件頭信息;
file.WriteHuge(lpBI, dwDIBSize);
//將位圖信息(信息頭結(jié)構(gòu)、顏色表、像素?cái)?shù)據(jù))寫入文件;
::GlobalUnlock((HGLOBAL) m_hDIB);
EndWaitCursor();
SetModifiedFlag(FALSE); // 將文檔設(shè)為“干凈”標(biāo)志,表示此后文檔不需要存盤提示;
return TRUE;
}
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
VC++圖像處理編程 - LiteQ的日志 - 網(wǎng)易博客
TIF圖像處理
Visual C++ 實(shí)現(xiàn)數(shù)字圖像增強(qiáng)處理
保存MFC的CBitmap對(duì)象中的圖象到一個(gè)BMP文件中
vc 保存Bitmap到文件
數(shù)字圖象運(yùn)動(dòng)檢測
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服