zoukankan      html  css  js  c++  java
  • 【转】构造自己的DIB类

    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

  • 相关阅读:
    【次大gcd】#uoj #48. 【UR #3】核聚变反应强度
    1591:数字计数
    数位DP模板
    1588:数字游戏
    [NOIP 2017普及组 No.1] 成绩
    [NOIP 2017普及组 No.3] 棋盘
    Apache(httpd)实现反向代理
    注册阿里云域名
    SSH常用命令
    Linux yum 安装Java和MySQL
  • 原文地址:https://www.cnblogs.com/cppskill/p/8057436.html
Copyright © 2011-2022 走看看