直方图

自定义的图象类中的得到直方图函数,参数iClrChannel为rgb分量之一,piGrays为该分量的256灰度级。  
  void   CImage::GetHistogram(int   *piGrays,   int   iClrChannel)  
  {  
  if(m_hBmp   ==   NULL)   return;  
  for(int   i   =   0;   i   <   256;   i++)  
  {  
  piGrays[i]   =   0;  
  }  
  ASSERT(iClrChannel   >=   0   &&   iClrChannel   <=   3);  
  LPSTR   lpBmp   =   (LPSTR)GlobalLock(m_hBmp);  
  BYTE*   lpBmpBits   =   (BYTE*)GetBmpBits(lpBmp);  
   
  CRect   rcData   =   GetDataRect();  
  int   row,   col;  
  int   iPixel=0;  
  BYTE   r,   g,   b;  
  r   =   g   =   b   =   0;  
   
  switch(m_nBitCount)  
  {  
  case   24:  
  {  
  if(iClrChannel   ==   3/*luminary*/)  
  {  
  BYTE*   pData   =   NULL;  
  for(row=rcData.top;   row<rcData.bottom;   row++)  
  {  
  for(col=rcData.left;col<rcData.right;col++)  
  {  
  pData   =   (BYTE*)lpBmpBits    
  +   row   *   m_nScanWidth   +   3*col;  
  piGrays[(pData[0]+pData[1]+pData[2])/3]++;  
  }  
  }  
  }  
  else  
  {  
      for(row   =   rcData.top;   row   <   rcData.bottom;   row++)  
      {  
  iPixel   =     iClrChannel   +   row   *   m_nScanWidth    
  +   rcData.left*3;//origin   pix   of   the   row  
  for(col   =   rcData.left;   col   <   rcData.right;   col++)  
  {  
  piGrays[lpBmpBits[iPixel]]++;  
  iPixel   +=   3;  
  }  
      }  
  }  
  break;  
  }  
  case   8:  
  {  
  PALETTEENTRY   PaletteColors[256];  
  if(m_pPalBmp->GetPaletteEntries(0,   256,   PaletteColors)  
  !=   256   ) break;  
  for(row   =   rcData.top;   row   <   rcData.bottom;   row++)  
  {  
  iPixel   =   row   *   m_nScanWidth   +   rcData.left;  
  for(col   =   rcData.left;   col   <   rcData.right;   col++)  
  {  
  r   =   PaletteColors[lpBmpBits[iPixel]].peRed;  
  g   =   PaletteColors[lpBmpBits[iPixel]].peGreen;  
  b   =   PaletteColors[lpBmpBits[iPixel]].peBlue;  
  iPixel++;  
  switch(iClrChannel)  
  {  
  case   3:/*lum*/ piGrays[(r+g+b)/3]++;break;  
  case   2:/*red*/   piGrays[r]++;break;  
  case   1:/*green*/  
  piGrays[g]++;break;  
  case   0:/*blue*/ piGrays[b]++;break;  
  }  
  }  
  }  
  break;  
  }  
  }  
  GlobalUnlock(m_hBmp);  
  }  
   
  m_hBmp为bmp图象中除去bmpfileheader后的数据,也就是PBMPINFOHEADER这个指针。用的HANDLE,所以需要先“GlobalLock”。  
  用这个函数得到:HANDLE   WINAPI   ReadBmpFile(CFile&   file)  
  {  
  BITMAPFILEHEADER   bmfHeader;  
  DWORD   dwBitsSize;  
  HANDLE   hBMP;  
  LPSTR   pBMP;  
   
  //get   length   of   Bmp   in   bytes   for   use   when   reading  
  dwBitsSize   =   file.GetLength();  
   
  //Go   read   the   Bmp   file   header   and   check   if   it's   valid.  
  file.SeekToBegin();  
  if   (file.Read((LPSTR)&bmfHeader,   sizeof(bmfHeader))   !=   sizeof(bmfHeader))  
  {  
  file.Close();  
  return   NULL;  
  }  
   
  if   (bmfHeader.bfType   !=   BMP_FILE_TYPE)  
  {  
  CString   str1,   str2;  
  str1.Format("此程序只能处理   BMP   图片!");  
  str2.Format("文件格式错误");  
  ::MessageBox(NULL,str1,str2,MB_ICONERROR|MB_OK);  
   
  file.Close();  
  return   NULL;  
  }  
   
   
  //Allocate   memory   for   Bmp  
  hBMP   =   (HANDLE)   ::GlobalAlloc(GHND,   dwBitsSize);  
  if   (hBMP   ==   0)  
  {  
  file.Close();  
  return   NULL;  
  }  
  pBMP   =   (LPSTR)   ::GlobalLock((HGLOBAL)   hBMP);  
   
  //   read   the   bits.  
     
  if   (file.ReadHuge(pBMP,   dwBitsSize   -   sizeof(BITMAPFILEHEADER))   !=  
  dwBitsSize   -   sizeof(BITMAPFILEHEADER)   )  
  {  
  ::GlobalUnlock((HGLOBAL)   hBMP);  
  ::GlobalFree((HGLOBAL)   hBMP);  
  file.Close();  
  return   NULL;  
  }  
   
  file.Close();  
  ::GlobalUnlock((HGLOBAL)   hBMP);  
  return   hBMP;  
  }  
   
  GetBmpBits函数用来得到图象数据。  
  LPSTR   WINAPI   GetBmpBits(LPSTR   lpBmp)  
  {  
  return   (lpBmp   +   *(LPDWORD)lpBmp   +   PaletteSize(lpBmp));  
  }  
   
  对24位色图象来说,用上边的东东就可以得到灰度直方图。对8位(256)色图象来说,需要调色板的介入。  
  WORD   WINAPI   PaletteSize(LPSTR   lpBmp)  
  {  
        //   calculate   the   size   required   by   the   palette  
        if   (IS_WIN30_BMP   (lpBmp))  
      return   (WORD)(::BmpNumColors(lpBmp)   *   sizeof(RGBQUAD));  
        else  
      return   (WORD)(::BmpNumColors(lpBmp)   *   sizeof(RGBTRIPLE));  
  }  
   
  WORD   WINAPI   BmpNumColors(LPSTR   lpBmp)  
  {  
  WORD   wBitCount;     //   Bmp   bit   count  
   
  /*     Calculate   the   number   of   colors   in   the   color   table   based   on  
    *     the   number   of   bits   per   pixel   for   the   Bmp.  
    */  
  if   (IS_WIN30_BMP(lpBmp))  
  wBitCount   =   ((LPBITMAPINFOHEADER)lpBmp)->biBitCount;  
  else  
  wBitCount   =   ((LPBITMAPCOREHEADER)lpBmp)->bcBitCount;  
   
  /*   return   number   of   colors   based   on   bits   per   pixel   */  
  switch   (wBitCount)  
  {  
  case   1:  
  return   2;  
   
  case   4:  
  return   16;  
   
  case   8:  
  return   256;  
   
  default:  
  return   0;  
  }  
  }  
   
  得到调色板:  
  BOOL   WINAPI   CreateBmpPalette(HANDLE   hBmp,   CPalette*   pPal)  
  {  
  LPLOGPALETTE   lpPal;           //   pointer   to   a   logical   palette  
  HANDLE   hLogPal;                   //   handle   to   a   logical   palette  
  WORD   wNumColors;                 //   number   of   colors   in   color   table  
  LPSTR   lpBmp;                         //   pointer   to   packed-Bmp  
  LPBITMAPINFO   lpbmi;           //   pointer   to   BITMAPINFO   structure   (Win3.0)  
  LPBITMAPCOREINFO   lpbmc;   //   pointer   to   BITMAPCOREINFO   structure   (OS/2)  
  BOOL   bResult=FALSE; //   return   value  
   
  //if   handle   to   Bmp   is   invalid,   return   FALSE  
  if   (hBmp   ==   NULL)  
      return   FALSE;  
   
        lpBmp   =   (LPSTR)   ::GlobalLock((HGLOBAL)   hBmp);  
   
        //   get   pointer   to   BITMAPINFO   (Win   3.0)  
        lpbmi   =   (LPBITMAPINFO)lpBmp;  
   
        //   get   pointer   to   BITMAPCOREINFO   (OS/2)  
        lpbmc   =   (LPBITMAPCOREINFO)lpBmp;  
   
        //   get   the   number   of   colors   in   the   Bmp  
        wNumColors   =   BmpNumColors(lpBmp);  
   
        if(wNumColors   ==0   ) //there   is   no   palette   in   the   bmp  
        return   FALSE;  
   
  //   allocate   memory   block   for   logical   palette    
  hLogPal   =   ::GlobalAlloc(GHND,   sizeof(LOGPALETTE)  
  +   sizeof(PALETTEENTRY)  
  *   wNumColors);  
   
  //   if   three   is   not   enough   memory,   clean   up   and   return   NULL    
  if   (hLogPal   ==   0)  
  {  
  ::GlobalUnlock((HGLOBAL)   hBmp);  
  return   FALSE;  
  }  
   
  lpPal   =   (LPLOGPALETTE)   ::GlobalLock((HGLOBAL)   hLogPal);  
   
  //set   version   and   number   of   palette   entries    
  lpPal->palVersion   =   PALVERSION;  
  lpPal->palNumEntries   =   (WORD)wNumColors;  
   
  if   (IS_WIN30_BMP(lpBmp)) //   is   this   a   Win   3.0   Bmp?    
  for   (int   i   =   0;   i   <   (int)wNumColors;   i++)  
  {  
  lpPal->palPalEntry[i].peRed   =   lpbmi->bmiColors[i].rgbRed;  
  lpPal->palPalEntry[i].peGreen   =   lpbmi->bmiColors[i].rgbGreen;  
  lpPal->palPalEntry[i].peBlue   =   lpbmi->bmiColors[i].rgbBlue;  
  lpPal->palPalEntry[i].peFlags   =   0;  
  }  
  else  
  for   (int   i   =   0;   i   <   (int)wNumColors;   i++)  
  {  
  lpPal->palPalEntry[i].peRed   =   lpbmc->bmciColors[i].rgbtRed;  
  lpPal->palPalEntry[i].peGreen   =   lpbmc->bmciColors[i].rgbtGreen;  
  lpPal->palPalEntry[i].peBlue   =   lpbmc->bmciColors[i].rgbtBlue;  
  lpPal->palPalEntry[i].peFlags   =   0;  
  }  
   
  //create   the   palette   and   get   handle   to   it  
  bResult   =   pPal->CreatePalette(lpPal);  
  ::GlobalUnlock((HGLOBAL)   hLogPal);  
  ::GlobalFree((HGLOBAL)   hLogPal);  
   
  ::GlobalUnlock((HGLOBAL)   hBmp);  
   
  return   bResult;  
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值