構造自己的DIB類

 
查看文章
   
構造自己的DIB類
2007-05-05 11:44

MFC沒有封裝DIB,我們可以自己構造自己的DIB類,在這裏我用的類名是CDibImage。裏面我還添加了部分常用的圖像處理函數。如點運算中的閾值變換函數ThresholdTrans()等等。希望對大家有所幫助。更重要的是理解,否則你是不會用的。

頭文件DibImage.h代碼

#if !defined(AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_)
#define AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

DECLARE_HANDLE(HDIB);   // DIB句柄
#define PALVERSION    0x300 // DIB常量

/* DIB宏 */
// 判斷是否是Win 3.0的DIB
#define IS_WIN30_DIB(lpbi)   ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
// 計算矩形區域的寬度
#define RECTWIDTH(lpRect)      ((lpRect)->right - (lpRect)->left)
// 計算矩形區域的高度
#define RECTHEIGHT(lpRect)     ((lpRect)->bottom - (lpRect)->top)

// 在計算圖像大小時,採用公式:biSizeImage = biWidth' × biHeight。
// 是biWidth',而不是biWidth,這裏的biWidth'必須是4的整倍數,表示
// 大於或等於biWidth的,離4最近的整倍數。WIDTHBYTES就是用來計算
// biWidth'
#define WIDTHBYTES(bits)     (((bits) + 31) / 32 * 4)

// Dib文件頭標誌(字符串"BM",寫DIB時用到該常數)
#define DIB_HEADER_MARKER    ((WORD) ('M' << 8) | 'B')

class CDibImage  
{
// Constructor and Destructor ///////////////////////////////
public:
CDibImage();
virtual ~CDibImage();

// function /////////////////////////////////////////////////
public:
//DIB函數
BOOL     PaintDIB (HDC, LPRECT, HDIB, LPRECT, CPalette* pPal);
BOOL     CreateDIBPalette(HDIB hDIB, CPalette* cPal);
LPSTR    FindDIBBits (LPSTR lpbi);
DWORD    DIBWidth (LPSTR lpDIB);
DWORD    DIBHeight (LPSTR lpDIB);
WORD     PaletteSize (LPSTR lpbi);
WORD     DIBNumColors (LPSTR lpbi);
HGLOBAL CopyHandle (HGLOBAL h);

BOOL     SaveDIB (HDIB hDib, CFile& file);
HDIB     ReadDIBFile(CFile& file);
//點運算函數
BOOL ThresholdTrans(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, BYTE bThre);

};


#endif // !defined(AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_)

/***************************************************************************************************************/

實現部分DibImage.cpp代碼

#include "stdafx.h"
#include "Image.h"
#include "DibImage.h"
#include <math.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDibImage::CDibImage()
{

}

CDibImage::~CDibImage()
{

}

//////////////////////////////////////////////////////////////////////
// DIB函數
//////////////////////////////////////////////////////////////////////

/*************************************************************************
* 函數名稱:
*    PaintDIB()
* 參數:
*    HDC hDC             - 輸出設備DC
*    LPRECT lpDCRect     - 繪製矩形區域
*    HDIB hDIB           - 指向DIB對象的指針
*    LPRECT lpDIBRect    - 要輸出的DIB區域
*    CPalette* pPal      - 指向DIB對象調色板的指針
* 返回值:
*    BOOL                - 繪製成功返回TRUE,否則返回FALSE。
* 說明:
*    該函數主要用來繪製DIB對象。其中調用了StretchDIBits()或者
* SetDIBitsToDevice()來繪製DIB對象。輸出的設備由由參數hDC指
* 定;繪製的矩形區域由參數lpDCRect指定;輸出DIB的區域由參數
* lpDIBRect指定。
************************************************************************/
BOOL CDibImage::PaintDIB(HDC      hDC,
      LPRECT   lpDCRect,
      HDIB     hDIB,
      LPRECT   lpDIBRect,
      CPalette* pPal)
{
LPSTR     lpDIBHdr;             // BITMAPINFOHEADER指針
LPSTR     lpDIBBits;            // DIB象素指針
BOOL      bSuccess=FALSE;       // 成功標誌
HPALETTE hPal=NULL;            // DIB調色板
HPALETTE hOldPal=NULL;         // 以前的調色板

if (hDIB == NULL)
{
   return FALSE;
}

lpDIBHdr   = (LPSTR)::GlobalLock((HGLOBAL) hDIB);// 鎖定DIB
lpDIBBits = FindDIBBits(lpDIBHdr); // 找到DIB圖像象素起始位置

if (pPal != NULL)      // 獲取DIB調色板,並選中它
{
   hPal = (HPALETTE) pPal->m_hObject;
   hOldPal = ::SelectPalette(hDC, hPal, TRUE); // 選中調色板
}

::SetStretchBltMode(hDC, COLORONCOLOR);    // 設置顯示模式

// 判斷是調用StretchDIBits()還是SetDIBitsToDevice()來繪製DIB對象
if ((RECTWIDTH(lpDCRect)   == RECTWIDTH(lpDIBRect)) &&
     (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
{
   // 原始大小,不用拉伸。
   bSuccess = ::SetDIBitsToDevice(hDC,                     // hDC
            lpDCRect->left,              // DestX
            lpDCRect->top,               // DestY
            RECTWIDTH(lpDCRect),         // nDestWidth
            RECTHEIGHT(lpDCRect),        // nDestHeight
            lpDIBRect->left,             // SrcX
            (int)DIBHeight(lpDIBHdr) -
            lpDIBRect->top -
            RECTHEIGHT(lpDIBRect),    // SrcY
            0,                           // nStartScan
            (WORD)DIBHeight(lpDIBHdr),   // nNumScans
            lpDIBBits,                   // lpBits
            (LPBITMAPINFO)lpDIBHdr,      // lpBitsInfo
            DIB_RGB_COLORS);             // wUsage
}
     else
{
   // 非原始大小,拉伸。
   bSuccess = ::StretchDIBits(hDC,                           // hDC
           lpDCRect->left,                  // DestX
           lpDCRect->top,                   // DestY
           RECTWIDTH(lpDCRect),             // nDestWidth
           RECTHEIGHT(lpDCRect),            // nDestHeight
           lpDIBRect->left,                 // SrcX
           lpDIBRect->top,                  // SrcY
           RECTWIDTH(lpDIBRect),            // wSrcWidth
           RECTHEIGHT(lpDIBRect),           // wSrcHeight
           lpDIBBits,                       // lpBits
           (LPBITMAPINFO)lpDIBHdr,          // lpBitsInfo
           DIB_RGB_COLORS,                  // wUsage
           SRCCOPY);                        // dwROP
}
  
::GlobalUnlock((HGLOBAL) hDIB);     // 解除鎖定
if (hOldPal != NULL)
{
   ::SelectPalette(hDC, hOldPal, TRUE); // 恢復以前的調色板
}
return bSuccess;
}

/*************************************************************************
* 函數名稱:
*    CreateDIBPalette()
* 參數:
*    HDIB hDIB           - 指向DIB對象的指針
*    CPalette* pPal      - 指向DIB對象調色板的指針
* 返回值:
*    BOOL                - 創建成功返回TRUE,否則返回FALSE。
* 說明:
*    該函數按照DIB創建一個邏輯調色板,從DIB中讀取顏色表並存到調色板中,
* 最後按照該邏輯調色板創建一個新的調色板,並返回該調色板的句柄。這樣
* 可以用最好的顏色來顯示DIB圖像。
************************************************************************/
BOOL CDibImage::CreateDIBPalette(HDIB hDIB, CPalette* pPal)
{

LPLOGPALETTE lpPal;   // 指向邏輯調色板的指針
HANDLE hLogPal;    // 邏輯調色板的句柄
HPALETTE hPal = NULL; // 調色板的句柄
int i;      // 循環變量
WORD wNumColors;   // 顏色表中的顏色數目
LPSTR lpbi;     // 指向DIB的指針
LPBITMAPINFO lpbmi;   // 指向BITMAPINFO結構的指針(Win3.0)
LPBITMAPCOREINFO lpbmc; // 指向BITMAPCOREINFO結構的指針
BOOL bWinStyleDIB;   // 表明是否是Win3.0 DIB的標記
BOOL bResult = FALSE; // 創建結果

if (hDIB == NULL)
{
   return FALSE;
}
  
lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); // 鎖定DIB
lpbmi = (LPBITMAPINFO)lpbi;   // 獲取指向BITMAPINFO結構的指針(Win3.0)
lpbmc = (LPBITMAPCOREINFO)lpbi; // 獲取指向BITMAPCOREINFO結構的指針
wNumColors = DIBNumColors(lpbi);// 獲取DIB中顏色表中的顏色數目

if (wNumColors != 0)
{
   // 分配爲邏輯調色板內存
   hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
          + sizeof(PALETTEENTRY)
          * wNumColors);
   // 如果內存不足,退出
   if (hLogPal == 0)
   {
    ::GlobalUnlock((HGLOBAL) hDIB); // 解除鎖定
    return FALSE;
   }
  
   lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);  
   lpPal->palVersion = PALVERSION;    // 設置版本號
   lpPal->palNumEntries = (WORD)wNumColors;// 設置顏色數目
   bWinStyleDIB = IS_WIN30_DIB(lpbi);   // 判斷是否是WIN3.0的DIB

   // 讀取調色板
   for (i = 0; i < (int)wNumColors; i++)
   {
    if (bWinStyleDIB)
    {
     // 讀取紅色綠色藍色分量
     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
    {
     // 讀取紅色綠色藍色分量
     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;
    }
   }
   
   bResult = pPal->CreatePalette(lpPal);// 按照邏輯調色板創建調色板,並返回指針
   ::GlobalUnlock((HGLOBAL) hLogPal); // 解除鎖定
   ::GlobalFree((HGLOBAL) hLogPal); // 釋放邏輯調色板
}

::GlobalUnlock((HGLOBAL) hDIB);    // 解除鎖定
return bResult;
}

/*************************************************************************
* 函數名稱:
*    FindDIBBits()
* 參數:
*    LPSTR lpbi          - 指向DIB對象的指針
* 返回值:
*    LPSTR               - 指向DIB圖像象素起始位置
* 說明:
*    該函數計算DIB中圖像象素的起始位置,並返回指向它的指針。
************************************************************************/
LPSTR CDibImage::FindDIBBits(LPSTR lpbi)
{
return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi));
}

/*************************************************************************
* 函數名稱:
*    DIBWidth()
* 參數:
*    LPSTR lpbi          - 指向DIB對象的指針
* 返回值:
*    DWORD               - DIB中圖像的寬度
* 說明:
*    該函數返回DIB中圖像的寬度。對於Windows 3.0 DIB,返回BITMAPINFOHEADER
* 中的biWidth值;對於其它返回BITMAPCOREHEADER中的bcWidth值。
************************************************************************/
DWORD CDibImage::DIBWidth(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi; // 指向BITMAPINFO結構的指針(Win3.0)
LPBITMAPCOREHEADER lpbmc; // 指向BITMAPCOREINFO結構的指針
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;

// 返回DIB中圖像的寬度
if (IS_WIN30_DIB(lpDIB))
{  
   return lpbmi->biWidth;   // 對於Windows 3.0 DIB,返回lpbmi->biWidth
}
else
{  
   return (DWORD)lpbmc->bcWidth; // 對於其它格式的DIB,返回lpbmc->bcWidth
}
}

/*************************************************************************
* 函數名稱:
*    DIBHeight()
* 參數:
*    LPSTR lpDIB         - 指向DIB對象的指針
* 返回值:
*    DWORD               - DIB中圖像的高度
* 說明:
*    該函數返回DIB中圖像的高度。對於Windows 3.0 DIB,返回BITMAPINFOHEADER
* 中的biHeight值;對於其它返回BITMAPCOREHEADER中的bcHeight值。
************************************************************************/
DWORD CDibImage::DIBHeight(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi; // 指向BITMAPINFO結構的指針(Win3.0)
LPBITMAPCOREHEADER lpbmc; // 指向BITMAPCOREINFO結構的指針
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;

// 返回DIB中圖像的寬度
if (IS_WIN30_DIB(lpDIB))
{  
   return lpbmi->biHeight;   // 對於Windows 3.0 DIB,返回lpbmi->biHeight
}
else
{  
   return (DWORD)lpbmc->bcHeight; // 對於其它格式的DIB,返回lpbmc->bcHeight
}
}

/*************************************************************************
* 函數名稱:
*    PaletteSize()
* 參數:
*    LPSTR lpbi          - 指向DIB對象的指針
* 返回值:
*    WORD                - DIB中調色板的大小
* 說明:
*    該函數返回DIB中調色板的大小。對於Windows 3.0 DIB,返回顏色數目×
* RGBQUAD的大小;對於其它返回顏色數目×RGBTRIPLE的大小。
************************************************************************/
WORD CDibImage::PaletteSize(LPSTR lpbi)
{
// 計算DIB中調色板的大小
if (IS_WIN30_DIB (lpbi))
{
   //返回顏色數目×RGBQUAD的大小
   return (WORD)(DIBNumColors(lpbi) * sizeof(RGBQUAD));
}
else
{
   //返回顏色數目×RGBTRIPLE的大小
   return (WORD)(DIBNumColors(lpbi) * sizeof(RGBTRIPLE));
}
}

/*************************************************************************
* 函數名稱:
*    DIBNumColors()
* 參數:
*    LPSTR lpbi          - 指向DIB對象的指針
* 返回值:
*    WORD                - 返回調色板中顏色的種數
* 說明:
*    該函數返回DIB中調色板的顏色的種數。對於單色位圖,返回2,
* 對於16色位圖,返回16,對於256色位圖,返回256;對於真彩色
* 位圖(24位),沒有調色板,返回0。
************************************************************************/
WORD CDibImage::DIBNumColors(LPSTR lpbi)
{
WORD wBitCount;

// 對於Windows的DIB, 實際顏色的數目可以比象素的位數要少。
// 對於這種情況,則返回一個近似的數值。

// 判斷是否是WIN3.0 DIB
if (IS_WIN30_DIB(lpbi))
{
   DWORD dwClrUsed;
   dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed; // 讀取dwClrUsed值
  
   if (dwClrUsed != 0)
   {
    // 如果dwClrUsed(實際用到的顏色數)不爲0,直接返回該值
    return (WORD)dwClrUsed;
   }
}

// 讀取象素的位數
if (IS_WIN30_DIB(lpbi))
{  
   wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount; // 讀取biBitCount值
}
else
{  
   wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount; // 讀取biBitCount值
}

// 按照象素的位數計算顏色數目
switch (wBitCount)
{
   case 1:
    return 2;
    break;
   case 4:
    return 16;
    break;
   case 8:
    return 256;
    break;
   default:
    return 0;
    break;
}
}

/*************************************************************************
* 函數名稱:
*    CopyHandle()
* 參數:
*    HGLOBAL h           - 要複製的內存區域
* 返回值:
*    HGLOBAL             - 複製後的新內存區域
* 說明:
*    該函數複製指定的內存區域。返回複製後的新內存區域,出錯時返回0。
************************************************************************/
HGLOBAL CDibImage::CopyHandle (HGLOBAL h)
{
if (h == NULL)
{
   return NULL;
}

DWORD dwLen = ::GlobalSize((HGLOBAL) h); // 獲取指定內存區域大小
HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen); // 分配新內存空間
if (hCopy != NULL)        // 判斷分配是否成功
{
   void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);
   void* lp      = ::GlobalLock((HGLOBAL) h);
  
   memcpy(lpCopy, lp, dwLen);
  
   ::GlobalUnlock(hCopy);
   ::GlobalUnlock(h);
}

return hCopy;
}

/*************************************************************************
* 函數名稱:
*    SaveDIB()
* 參數:
*    HDIB hDib           - 要保存的DIB
*    CFile& file         - 保存文件CFile
* 返回值:
*    BOOL                - 成功返回TRUE,否則返回FALSE或者CFileException
* 說明:
*    該函數將指定的DIB對象保存到指定的CFile中。該CFile由調用程序打開和關閉。
*************************************************************************/
BOOL CDibImage::SaveDIB(HDIB hDib, CFile& file)
{
BITMAPFILEHEADER bmfHdr; // Bitmap文件頭
LPBITMAPINFOHEADER lpBI; // 指向BITMAPINFOHEADER的指針
DWORD dwDIBSize;    // DIB大小

if (hDib == NULL)
{
   return FALSE;
}

// 讀取BITMAPINFO結構,並鎖定
lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
if (lpBI == NULL)
{
   return FALSE;
}

// 判斷是否是WIN3.0 DIB
if (!IS_WIN30_DIB(lpBI))
{
   // 不支持其它類型的DIB保存
   ::GlobalUnlock((HGLOBAL) hDib);
   return FALSE;
}

////////////////////////////////////////////////////////////////////////
// 填充文件頭///////////////////////////////////////////////////////////
bmfHdr.bfType = DIB_HEADER_MARKER;   // 文件類型"BM"

// 計算DIB大小時,最簡單的方法是調用GlobalSize()函數。但是全局內存大小並
// 不是DIB真正的大小,它總是多幾個字節。這樣就需要計算一下DIB的真實大小。

// 文件頭大小+顏色表大小
// (BITMAPINFOHEADER和BITMAPCOREHEADER結構的第一個DWORD都是該結構的大小)
dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI);

// 計算圖像大小
if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
{
   // 對於RLE位圖,沒法計算大小,只能信任biSizeImage內的值
   dwDIBSize += lpBI->biSizeImage;
}
else
{  
   DWORD dwBmBitsSize;    // 象素的大小
   dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))
    * lpBI->biHeight;   // 大小爲Width * Height
   dwDIBSize += dwBmBitsSize; // 計算出DIB真正的大小

   // 更新biSizeImage(很多BMP文件頭中biSizeImage的值是錯誤的)
   lpBI->biSizeImage = dwBmBitsSize;
}

// 計算文件大小:DIB大小+BITMAPFILEHEADER結構大小
bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);

// 兩個保留字
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;

// 計算偏移量bfOffBits,它的大小爲Bitmap文件頭大小+DIB頭大小+顏色表大小
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
              + PaletteSize((LPSTR)lpBI);

/////////////////////////////////////////////////////////////////////////
// 嘗試寫文件////////////////////////////////////////////////////////////
TRY
{  
   file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER)); // 寫文件頭
   file.WriteHuge(lpBI, dwDIBSize);      // 寫DIB頭和象素
}
CATCH (CFileException, e)
{
   ::GlobalUnlock((HGLOBAL) hDib);
   THROW_LAST();
}
END_CATCH

::GlobalUnlock((HGLOBAL) hDib);
return TRUE;
}

/*************************************************************************
* 函數名稱:
*    ReadDIBFile()
* 參數:
*    CFile& file         - 要讀取得文件文件CFile
* 返回值:
*    HDIB                - 成功返回DIB的句柄,否則返回NULL。
* 說明:
*    該函數將指定的文件中的DIB對象讀到指定的內存區域中。除BITMAPFILEHEADER
* 外的內容都將被讀入內存。
*************************************************************************/
HDIB CDibImage::ReadDIBFile(CFile& file)
{
BITMAPFILEHEADER bmfHeader;
HDIB hDIB;
LPSTR pDIB;
DWORD dwBitsSize;

dwBitsSize = file.GetLength();   // 獲取DIB(文件)長度(字節)

// 嘗試讀取DIB文件頭
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
{
   return NULL;
}
// 判斷是否是DIB對象,檢查頭兩個字節是否是"BM"
if (bmfHeader.bfType != DIB_HEADER_MARKER)
{
   return NULL;
}
// 爲DIB分配內存
hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
if (hDIB == 0)
{
   return NULL;
}

pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
   dwBitsSize - sizeof(BITMAPFILEHEADER) )   // 讀象素
{
   ::GlobalUnlock((HGLOBAL) hDIB);
   ::GlobalFree((HGLOBAL) hDIB);
   return NULL;
}

::GlobalUnlock((HGLOBAL) hDIB);
return hDIB;
}

/************************************************************************/
/* 點運算函數                                                                      */
/************************************************************************/

/*************************************************************************
* 函數名稱:
*    ThresholdTrans()
* 參數:
*    LPSTR lpDIBBits     - 指向源DIB圖像指針
*    LONG   lWidth        - 源圖像寬度(象素數)
*    LONG   lHeight       - 源圖像高度(象素數)
*    BYTE   bThre      - 閾值
* 返回值:
*    BOOL                - 成功返回TRUE,否則返回FALSE。
* 說明:
*    該函數用來對圖像進行閾值變換。對於灰度值小於閾值的象素直接設置
* 灰度值爲0;灰度值大於閾值的象素直接設置爲255。
************************************************************************/
BOOL CDibImage::ThresholdTrans(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, BYTE bThre)
{
unsigned char* lpSrc;     // 指向源圖像的指針
LONG i;        // 循環變量
LONG j;
LONG lLineBytes;      // 圖像每行的字節數
  
lLineBytes = WIDTHBYTES(lWidth * 8);// 計算圖像每行的字節數

for(i = 0; i < lHeight; i++)   // 每行
{  
   for(j = 0; j < lWidth; j++)   // 每列
   {
    // 指向DIB第i行,第j個象素的指針
    lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;   
   
    if ((*lpSrc) < bThre)   // 判斷是否小於閾值
    {
     *lpSrc = 0;
    }
    else
    {
     *lpSrc = 255;
    }
   }
}

return TRUE;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章