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. 金九银十跳槽季,程序员面试点解析之Java专场

    前言 近年来Java工程师这个岗位炙手可热,市场需求大,学习Java的人也越来越多,所以IT企业与求职者的选择都比较多,那么IT企业在面试时都会提哪些问题呢.下面为大家分享 Java高级工程师面试阿里 ...

  2. 怎样从外网访问内网Django?

    本地安装了一个Django,只能在局域网内访问,怎样从外网也能访问到本地的Django呢?本文将介绍具体的实现步骤. 准备工作 安装并启动Django 默认安装的Django端口是8000. 实现步骤 ...

  3. 在linux中安装memcache服务器

    挂载光盘   mkdir -p /media/cdrom   mount /dev/cdrom /media/cdrom   设置yum cd /etc/yum.repos.d/ mv CentOS- ...

  4. Android平台MediaCodec避坑指北

    https://www.jianshu.com/p/5d62a3cf0741 最近使用MediaCodec做编解码H264,写一点东西以免自己再次掉坑. 先说一下具体环境,使用的是,Windows10 ...

  5. 2019/3/19 wen 运算符

  6. php的serialize()函数和unserialize()函数

    适用情境:serialize()返回字符串,此字符串包含了表示value的字节流,可以存储于任何地方.这有利于存储或传递 PHP 的值,同时不丢失其类型和结构.比较有用的地方就是将数据存入数据库或记录 ...

  7. 获取微信access_token

    /** * 获取微信access_token * @return mixed */function get_access_token() { $appId = C('APPID'); $secret ...

  8. Scrapy学习笔记(5)-CrawlSpider+sqlalchemy实战

    基础知识 class scrapy.spiders.CrawlSpider 这是抓取一般网页最常用的类,除了从Spider继承过来的属性外,其提供了一个新的属性rules,它提供了一种简单的机制,能够 ...

  9. python之auto鼠标/键盘事件

    mouse_key.py import os import time import win32gui import win32api import win32con from ctypes impor ...

  10. 最菜的小鸟(mkdir -pv)

    命令 mkdir -pv /usr/local/modules/{openjdk,nginx,tomcat,mariadb}/{manifests,files,templates,lib,tests, ...