ZC: 搜索"DIB_HEADER_MARKER"时,看到的这个文章

http://blog.csdn.net/yyyuhan/article/details/2026652

 
查看文章
   
构造自己的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;
}

Z

【转】构造自己的DIB类的更多相关文章

  1. 构造字典:DictionaryBase类和SortedList类

    DictionaryBase 类 msdn对DictionaryBase的文档解释 泛型KeyValuePair类 msdnd对泛型KeyValuePair类的文档解释 SortedList类 RUN ...

  2. [转] web前端js构造无法销毁的类UUID识别码,识别浏览器设备唯一性

    用户行为统计在如今的前端生态中已是稀松寻常,如各种站长统计工具.识别用户访问客户端唯一性是必要的实现,对于web前端获取的设备信息,一般容易想到的是通过navigator.userAgent,但相同设 ...

  3. 构造Json对象串工具类

    import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.Property ...

  4. Java提高篇——静态代码块、构造代码块、构造函数以及Java类初始化顺序

    静态代码块:用staitc声明,jvm加载类时执行,仅执行一次构造代码块:类中直接用{}定义,每一次创建对象时执行.执行顺序优先级:静态块,main(),构造块,构造方法. 构造函数 public H ...

  5. android NDK 实用学习(三)- java端类对象的构造及使用

    1,读此文章前我假设你已经读过: android NDK 实用学习-获取java端类及其类变量 android NDK 实用学习-java端对象成员赋值和获取对象成员值 2,java端类对象的构造: ...

  6. C++ 类 、构造、 析构、 重载 、单例模式 学习笔记及练习

    一.拷贝构造函数 1.是一种特殊的构造函数,就是用一个已有的对象去构造其同类的副本对象,即对象克隆. class 类名 { 类名(类名& that) { 对类成员挨个赋值 ... } } 练习 ...

  7. C++面试常见问题——10派生类的构造与析构

    派生类的构造与析构 派生类的构造 派生时构造函数与析构函数不会被继承,需要重新定义派生类的构造函数与析构函数.派生类对象包含了基类对象的值,创建派生类时首先会调用基类的构造函数,若派生类中含有其它类对 ...

  8. C++派生类的拷贝构造

    一. 概述 通过几个简单的实验,回顾下派生类中拷贝构造的相关知识. 环境:Centos7 64位, g++ 4.8.5 在继承中,构造器与析构器均没有被继承下来.拷贝构造,也是一种构造,也没有被继承下 ...

  9. LinqToDB 源码分析——DataContext类

    LinqToDB框架是一个轻量级的ORM框架.当然,功能上来讲一定比不上Entity Framework的强大.但是在使用上总让笔者感觉有一点Entity Framework的影子.笔者想过可能的原因 ...

随机推荐

  1. right spindle supply short to gnd

    hardware guy found that the R1004 lead to this error, but this error should not be checked, because ...

  2. qt裁剪

    1. qt裁剪是什么,qt有哪些模块 1.1 2. windows消息机制,qt的signal slot,android/ios消息机制?

  3. sitemap index

    https://docs.djangoproject.com/en/2.1/ref/contrib/sitemaps/ very good

  4. Golang错误处理函数defer、panic、recover、errors.New介绍

    在默认情况下,当发生错误(panic)后,程序就会终止运行 如果发生错误后,可以捕获错误,并通知管理人员(邮件或者短信),程序还可以继续运行,这当然无可厚非 errors.New("错误信息 ...

  5. JS方法转字符串

    今天接手的代码比较特殊,需要动态拼接一个table,每一行<tr>都是通过转换为字符串,再拼接在一起放到tbody中的. 其中有的td标签中有a标签,需要给a标签添加点击事件,参数好多,动 ...

  6. oracle 12c AUTO_SAMPLE_SIZE动态采用工作机制

    The ESTIMATE_PERCENT parameter in DBMS_STATS.GATHER_*_STATS procedures controls the percentage of ro ...

  7. python简说(十三)递归

    #递归就是函数自己调用自己count = 0# def abc():# pass# abc()最多循环999次

  8. CEF 文件下载

    转载:https://blog.csdn.net/liuyan20092009/article/details/53819473?locationNum=6&fps=1 转载:https:// ...

  9. Jbarcode 条形码生成工具

    一.准备jar包 https://sourceforge.net/projects/jbcode/?source=typ_redirect 二.编写工具类 package com.example.de ...

  10. 【python010-数组】

    1.创建列表 *创建普通列表 >>> member = ['尘封','破冰','python']>>> member['尘封', '破冰', 'python'] * ...