日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BMP格式图像的显示

發布時間:2023/12/13 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BMP格式图像的显示 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?  使用多文檔編程 也可以使用單文檔編程

  建立一個DIB圖像的顯示類 ImageDib

  成員變量:

  4個指針:

    LPBYTE m_lpDib;??????//指向DIB的指針
    LPBITMAPINFOHEADER m_lpBmpInfoHead; ?//圖像信息頭指針

    LPRGBQUAD m_lpColorTable; ????//圖像顏色表指針
    unsigned char * m_pImgData; ????//圖像數據指針

  4個普通變量(存放圖像的參數):
???   int m_imgWidth;???????//圖像的寬,像素為單位
?   ? int m_imgHeight; ??????//圖像的高,像素為單位
    int m_nBitCount;??????//每像素占的位數
?    int m_nColorTableLength; ?????//顏色表長度(多少個表項)
  1個句柄:
????   HPALETTE m_hPalette;?????//邏輯調色板句柄

  成員函數:

  帶參數構造函數  ImageDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable,?unsigned char *pImgData);?????????? //帶參數的構造函數

View Code ImageDib::ImageDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable,unsigned char *pImgData) {//如果沒有位圖數據傳入,我們認為是空的DIB,此時不分配DIB內存if(pImgData==NULL){m_lpDib=NULL;m_lpColorTable=NULL;m_pImgData=NULL; // 圖像數據m_lpBmpInfoHead=NULL; // 圖像信息頭m_hPalette = NULL;}else{//如果有位圖數據傳入//可以通過調用ReplaceDib()來實現 代碼一樣的//ReplaceDib(size,nBitCount,lpColorTable,pImgData);//圖像的寬、高、每像素位數等成員變量賦值m_imgWidth=size.cx;m_imgHeight=size.cy;m_nBitCount=nBitCount;//根據每像素位數,計算顏色表長度m_nColorTableLength=ComputeColorTabalLength(nBitCount);//每行像素所占字節數,必須擴展成4的倍數int lineByte=(m_imgWidth*nBitCount/8+3)/4*4;//位圖數據緩沖區的大小(圖像大小)int imgBufSize=m_imgHeight*lineByte;//為m_lpDib一次性分配內存,生成DIB結構m_lpDib=new BYTE [sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableLength+imgBufSize];//填寫BITMAPINFOHEADER結構m_lpBmpInfoHead = (LPBITMAPINFOHEADER) m_lpDib;m_lpBmpInfoHead->biSize = sizeof(BITMAPINFOHEADER);m_lpBmpInfoHead->biWidth = m_imgWidth;m_lpBmpInfoHead->biHeight = m_imgHeight;m_lpBmpInfoHead->biPlanes = 1;m_lpBmpInfoHead->biBitCount = m_nBitCount;m_lpBmpInfoHead->biCompression = BI_RGB;m_lpBmpInfoHead->biSizeImage = 0;m_lpBmpInfoHead->biXPelsPerMeter = 0;m_lpBmpInfoHead->biYPelsPerMeter = 0;m_lpBmpInfoHead->biClrUsed = m_nColorTableLength;m_lpBmpInfoHead->biClrImportant = m_nColorTableLength;//調色板句柄初始化為空,有顏色表時,MakePalette()函數要生成新的調色板m_hPalette = NULL;//如果有顏色表,則將顏色表拷貝進DIB的顏色表位置if(m_nColorTableLength!=0){//m_lpColorTable指向DIB顏色表的起始位置m_lpColorTable=(LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER));//顏色表拷貝memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD) * m_nColorTableLength);//創建邏輯調色板 MakePalette();}//m_pImgData指向DIB位圖數據起始位置m_pImgData = (LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD) * m_nColorTableLength;//拷貝圖像數據進DIB位圖數據區 memcpy(m_pImgData,pImgData,imgBufSize);}}

?

  讀文件:  ?   BOOL Read(LPCTSTR lpszPathName); ??//DIB讀函數

View Code BOOL ImageDib::Read(LPCTSTR lpszPathName) {//讀模式打開圖像文件 CFile file;if (!file.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite))return FALSE;BITMAPFILEHEADER bmfh;//讀取BITMAPFILEHEADER結構到變量bmfh中int nCount=file.Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));//為m_lpDib分配空間,讀取DIB進內存if(m_lpDib!=NULL) delete []m_lpDib;m_lpDib=new BYTE[file.GetLength() -sizeof(BITMAPFILEHEADER)];file.Read(m_lpDib, file.GetLength() -sizeof(BITMAPFILEHEADER));//m_lpBmpInfoHead位置為m_lpDib起始位置m_lpBmpInfoHead = (LPBITMAPINFOHEADER)m_lpDib;//為成員變量賦值m_imgWidth=m_lpBmpInfoHead->biWidth;m_imgHeight=m_lpBmpInfoHead->biHeight;m_nBitCount=m_lpBmpInfoHead->biBitCount; //計算顏色表長度m_nColorTableLength= ComputeColorTabalLength(m_lpBmpInfoHead->biBitCount);//如果有顏色表,則創建邏輯調色板m_hPalette = NULL;if(m_nColorTableLength!=0){m_lpColorTable=(LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER));MakePalette();}//m_pImgData指向DIB的位圖數據起始位置m_pImgData = (LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER) +sizeof(RGBQUAD) * m_nColorTableLength;return TRUE; }

?


??????寫文件:     BOOL Write(LPCTSTR lpszPathName);?????? //DIB寫函數

View Code BOOL ImageDib::Write(LPCTSTR lpszPathName) {//寫模式打開文件 CFile file;if (!file.Open(lpszPathName, CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive))return FALSE;//填寫文件頭結構 BITMAPFILEHEADER bmfh;bmfh.bfType = 0x4d42; // 'BM'bmfh.bfSize = 0;bmfh.bfReserved1 = bmfh.bfReserved2 = 0;bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +sizeof(RGBQUAD) * m_nColorTableLength; try {//文件頭結構寫進文件file.Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));//文件信息頭結構寫進文件file.Write(m_lpBmpInfoHead, sizeof(BITMAPINFOHEADER));//如果有顏色表的話,顏色表寫進文件if(m_nColorTableLength!=0)file.Write(m_lpColorTable, sizeof(RGBQUAD) * m_nColorTableLength);//位圖數據寫進文件int imgBufSize=(m_imgWidth*m_nBitCount/8+3)/4*4*m_imgHeight;file.Write(m_pImgData, imgBufSize);}catch(CException* pe) {pe->Delete();AfxMessageBox("write error");return FALSE;}//函數返回return TRUE; }

?


  計算顏色表長度:? int ComputeColorTabalLength(int nBitCount);?//計算顏色表的長度

View Code int ImageDib::ComputeColorTabalLength(int nBitCount) {int colorTableLength;switch(nBitCount) {case 1:colorTableLength = 2;break;case 4:colorTableLength = 16;break;case 8:colorTableLength = 256;break;case 16:case 24:case 32:colorTableLength = 0;break;default:ASSERT(FALSE);}ASSERT((colorTableLength >= 0) && (colorTableLength <= 256)); return colorTableLength; }

?


  創建邏輯調色板:? void MakePalette();??????//創建邏輯調色板

View Code void ImageDib::MakePalette() {//如果顏色表長度為0,則不創建邏輯調色板if(m_nColorTableLength == 0) return;//刪除舊的邏輯調色板句柄if(m_hPalette != NULL) ::DeleteObject(m_hPalette);//申請空間,根據顏色表生成LOGPALETTE結構LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) +m_nColorTableLength * sizeof(PALETTEENTRY)];pLogPal->palVersion = 0x300;pLogPal->palNumEntries = m_nColorTableLength;LPRGBQUAD m_lpDibQuad = (LPRGBQUAD) m_lpColorTable;for(int i = 0; i < m_nColorTableLength; i++) {pLogPal->palPalEntry[i].peRed = m_lpDibQuad->rgbRed;pLogPal->palPalEntry[i].peGreen = m_lpDibQuad->rgbGreen;pLogPal->palPalEntry[i].peBlue = m_lpDibQuad->rgbBlue;pLogPal->palPalEntry[i].peFlags = 0;m_lpDibQuad++;} //創建邏輯調色板m_hPalette = ::CreatePalette(pLogPal);//釋放空間 delete pLogPal; }

?


  讀取圖像維數:  CSize GetDimensions();?????//讀取圖像維數

View Code CSize ImageDib::GetDimensions() { if(m_lpDib == NULL) return CSize(0, 0);return CSize(m_imgWidth, m_imgHeight); }

?


  圖像繪制:  ??? BOOL Draw(CDC* pDC, CPoint origin, CSize size); //圖像繪制

View Code BOOL ImageDib::Draw(CDC* pDC, CPoint origin, CSize size) {HPALETTE hOldPal=NULL; //舊的調色板句柄if(m_lpDib == NULL) return FALSE; //如果DIB為空,則返回0if(m_hPalette != NULL) { //如果DIB有調色板//將調色板選進設備環境中hOldPal=::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);pDC->RealizePalette(); }pDC->SetStretchBltMode(COLORONCOLOR); //設置位圖伸縮模式//將DIB在pDC所指向的設備上進行顯示::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,0, 0, m_lpBmpInfoHead->biWidth, m_lpBmpInfoHead->biHeight,m_pImgData,(LPBITMAPINFO) m_lpBmpInfoHead, DIB_RGB_COLORS, SRCCOPY);if(hOldPal!=NULL) //恢復舊的調色板::SelectPalette(pDC->GetSafeHdc(), hOldPal, TRUE);return TRUE; }

?


  用新的數據替代DIB:void ReplaceDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable,?unsigned char *pImgData);????????????? ?//用新的數據替換DIB

View Code void ImageDib::ReplaceDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable,unsigned char *pImgData) { //釋放原DIB所占空間 Empty();//成員變量賦值m_imgWidth=size.cx;m_imgHeight=size.cy;m_nBitCount=nBitCount;//計算顏色表的長度m_nColorTableLength=ComputeColorTabalLength(nBitCount);//每行像素所占字節數,擴展成4的倍數int lineByte=(m_imgWidth*nBitCount/8+3)/4*4;//位圖數據的大小int imgBufSize=m_imgHeight*lineByte;//為m_lpDib重新分配空間,以存放新的DIBm_lpDib=new BYTE [sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableLength+imgBufSize];//填寫位圖信息頭BITMAPINFOHEADER結構m_lpBmpInfoHead = (LPBITMAPINFOHEADER) m_lpDib;m_lpBmpInfoHead->biSize = sizeof(BITMAPINFOHEADER);m_lpBmpInfoHead->biWidth = m_imgWidth;m_lpBmpInfoHead->biHeight = m_imgHeight;m_lpBmpInfoHead->biPlanes = 1;m_lpBmpInfoHead->biBitCount = m_nBitCount;m_lpBmpInfoHead->biCompression = BI_RGB;m_lpBmpInfoHead->biSizeImage = 0;m_lpBmpInfoHead->biXPelsPerMeter = 0;m_lpBmpInfoHead->biYPelsPerMeter = 0;m_lpBmpInfoHead->biClrUsed = m_nColorTableLength;m_lpBmpInfoHead->biClrImportant = m_nColorTableLength;//調色板置空m_hPalette = NULL;//如果有顏色表,則將顏色表拷貝至新生成的DIB,并創建邏輯調色板if(m_nColorTableLength!=0){m_lpColorTable=(LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER));memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD) * m_nColorTableLength);MakePalette();}//m_pImgData指向DIB的位圖數據起始位置m_pImgData = (LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD) * m_nColorTableLength;//將新位圖數據拷貝至新的DIB中 memcpy(m_pImgData,pImgData,imgBufSize); }

?

  清理空間函數:  void Empty();???????????????????????? ?//清理空間

View Code void ImageDib::Empty() {//釋放DIB內存緩沖區if(m_lpDib != NULL) {delete [] m_lpDib;m_lpDib=NULL;m_lpColorTable=NULL;m_pImgData=NULL; m_lpBmpInfoHead=NULL;}//釋放邏輯調色板緩沖區if(m_hPalette != NULL){::DeleteObject(m_hPalette);m_hPalette = NULL;} }

?

  默認構造函數:

View Code ImageDib::ImageDib() {m_lpDib=NULL;//初始化m_lpDib為空。m_lpColorTable=NULL; //顏色表指針為空m_pImgData=NULL; //圖像數據指針為空m_lpBmpInfoHead=NULL; //圖像信息頭指針為空m_hPalette = NULL; //調色板為空 }

  默認析構函數:

View Code ImageDib::~ImageDib() {//釋放m_lpDib所指向的內存緩沖區if(m_lpDib != NULL) delete [] m_lpDib; //如果有調色板,釋放調色板緩沖區if(m_hPalette != NULL)::DeleteObject(m_hPalette); }

? 編寫好ImageDib類后,在doc文件類中添加一個ImageDib類的指針,在構造函數中new出來,在析構函數中delete,然后重寫OnOpenDocument()函數 在其中調用讀函數打開圖像 在View類的OnDraw()中調用ImageDib類的繪制函數 將圖像繪制在打開的新文件中

總結:編程的關鍵在于幾個指針的賦值,指向DIB的指針的分配空間,位圖信息頭等結構的賦值等等。

只要記住:

  BMP文件=位圖頭文件+位圖信息頭+顏色表+數據塊    (等號后邊的內容按順序寫的)

  DIB=位圖信息頭+顏色表+數據塊

  位圖信息=位圖信息頭+顏色表

這些圖像文件的存儲組成及順序,萬事OK!


???????

轉載于:https://www.cnblogs.com/Anidot/archive/2012/04/23/2466495.html

總結

以上是生活随笔為你收集整理的BMP格式图像的显示的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。