VisualC 6.0开发灰度位图处理

  • 发布于:2023-12-22
  • 134 人围观
  图像处理技术已经渗透到人类生活的各个领域并得到越来越多的应用,图像处理所涉及的图像格式有很多种,如TIF、JEMP、BMP等等,工程应用中经常要处理256级的灰度BMP图像,如通过黑白采集卡采集得到的图像。BMP灰度图像作为Windows环境下主要的图像格式之一,以其格式简单,适应性强而倍受欢迎。在进行图像处理时,操作图像中的像素值就要得到图像阵列;经过处理后的图像的像素值存储起来;显示图像时要正确实现调色板,结合这些问题,文章针对性的给出了操作灰度BMP图像时的部分函数实现代码及注释。

  一、 BMP位图操作

  BMP位图包括位图文件头结构BITMAPFILEHEADER、位图信息头结构BITMAPINFOHEADER、位图颜色表RGBQUAD和位图像素数据四部分。处理位图时要根据文件的这些结构得到位图文件大小、位图的宽、高、实现调色板、得到位图像素值等等。对于256级灰度图像每个像素用8bit表示颜色的索引值,这里要注意的一点是在BMP位图中,位图的每行像素值要填充到一个四字节边界,即位图每行所占的存储长度为四字节的倍数,不足时将多余位用0填充。

  在处理图像应用程序的文档类(CdibDoc.h)中声明如下宏及公有变量:

  #define WIDTHBYTES(bits) (((bits) 31) / 32 * 4)//计算图像每行象素所占的字节数目

  HANDLE m_hDIB;//存放位图数据的句柄

  CPalette* m_palDIB;//指向调色板Cpalette类的指针

  CSize m_sizeDoc; file://初始化视图的尺寸

  1、 读取灰度BMP位图

  根据BMP位图文件的结构,操作BMP位图文件读入数据,重载了文挡类的OnOpenDocument函数如下:

BOOL CDibDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
 CFile file;
 CFileException fe;
 if (!file.Open(lpszPathName, CFile::modeRead | CFile::shareDenyWrite, &fe))
 {
  AfxMessageBox("文件打不开");
  return FALSE;
  }//打开文件
 DeleteContents();//删除文挡
 BeginWaitCursor();
 BITMAPFILEHEADER bmfHeader;//定义位图文件头结构
 DWORD dwBitsSize;
 HANDLE hDIB;
 LPSTR pDIB;
 BITMAPINFOHEADER *bmhdr;//指向位图信息头结构的指针
 dwBitsSize = file.GetLength();//得到文件长度
 if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) !=
             sizeof(bmfHeader))
  return FALSE;
  if (bmfHeader.bfType != 0x4d42) file://检查是否为BMP文件
   return FALSE;
   hDIB=(HANDLE) ::GlobalAlloc(GMEM_MOVEABLE |
                 GMEM_ZEROINIT, dwBitsSize);
   file://申请缓冲区
   if (hDIB == 0)
   {
    return FALSE;
   }
   pDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);
   file://得到申请的缓冲区的指针
   if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
     dwBitsSize - sizeof(BITMAPFILEHEADER) )
   {
    ::GlobalUnlock((HGLOBAL)hDIB);
    hDIB=NULL;
    return FALSE;
    }//读数据,包括位图信息、位图颜色表、图像像素的灰度值
   bmhdr=(BITMAPINFOHEADER*)pDIB;//为指向位图信息头结构的指针付值
   ::GlobalUnlock((HGLOBAL)hDIB);
   if ((*bmhdr).biBitCount!=8) file://验证是否为8bit位图
    return FALSE;
    m_hDIB=hDIB;
    InitDIBData();
    file://自定义函数,根据读入的数据得到位图的宽、高、颜色表
    file:// 来得到初始化视的尺寸、生成调色板
    EndWaitCursor();
    SetPathName(lpszPathName);//设置存储路径
    SetModifiedFlag(FALSE); // 设置文件修改标志为FALSE
    return TRUE;
   }

  2、 灰度位图数据的存储

  为了将图像处理后所得到的像素值保存起来,重载了文档类的OnSaveDocument函数,其具体实现如下:

BOOL CDibDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
 CFile file;
 CFileException fe;
 BITMAPFILEHEADER bmfHdr; // 位图文件头结构
 LPBITMAPINFOHEADER lpBI; file://指向位图信息结构的指针
 DWORD dwDIBSize;
 if (!file.Open(lpszPathName, CFile::modeCreate |
   CFile::modeReadWrite | CFile::shareExclusive, &fe))
 {
  AfxMessageBox("文件打不开");
 }//打开文件
 BOOL bSuccess = FALSE;
 BeginWaitCursor();
 lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) m_hDIB);
 if (lpBI == NULL)
  return FALSE;
  dwDIBSize = *(LPDWORD)lpBI 256*sizeof(RGBQUAD);
   // Partial Calculation
  DWORD dwBmBitsSize;//BMP文件信息结构所占的字节数
  dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))  *lpBI->biHeight;//
万企互联
标签: