• 自建CDib类库


    转载自:http://www.cppblog.com/yefuhai/archive/2008/02/03/42477.html

     

     

    另一个:http://www.cnblogs.com/wqj1212/archive/2008/01/25/1052736.html

     

     

     

    // Dib.h: interface for the CDib class.
    //
    //////////////////////////////////////////////////////////////////////

    #if !defined(AFX_DIB_H__AC952C3A_9B6B_4319_8D6E_E7F509348A88__INCLUDED_)
    #define AFX_DIB_H__AC952C3A_9B6B_4319_8D6E_E7F509348A88__INCLUDED_

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

    class CDib : public CObject  
    {
    public:
     CDib();
     virtual ~CDib();
    //operations
    public:
     // 用于操作DIB的函数声明
     BOOL   ConstructPalette(HGLOBAL,CPalette* );         //构造逻辑调色板
     LPSTR  GetBits(LPSTR);                               //取得位图数据的入口地址
     DWORD  GetWidth(LPSTR);                              //取得位图的宽度
     DWORD  GetHeight(LPSTR);                             //取得位图的高度
     WORD   GetPalSize(LPSTR);                            //取得调色板的大小
     WORD   GetColorNum(LPSTR);                            //取得位图包含的颜色数目
     WORD   GetBitCount(LPSTR);                            //取得位图的颜色深度
     HGLOBAL   LoadFile(CFile&);                          //从文件中加载位图
     BOOL SaveFile(HGLOBAL hDib, CFile& file);


    // 在对图象进行处理时,针对位图的字节宽度必须是4的倍数的这一要求,
    // 我们设计了函数GetRequireWidth,来处理这种比较特殊的情况
     int     GetReqByteWidth(int );                     //转换后的字节数GetRequireByteWidth
     long    GetRectWidth(LPCRECT );                    //取得区域的宽度
     long    GetRectHeight(LPCRECT);                    //取得区域的高度
    public:
     void ClearMemory();
     void InitMembers();
    public:
     LPBITMAPINFO        lpbminfo; // 指向BITMAPINFO结构的指针
     LPBITMAPINFOHEADER  lpbmihrd; //指向BITMAPINFOHEADER结构的指针
     BITMAPFILEHEADER bmfHeader;  //BITMAPFILEHEADER结构
     LPSTR    lpdib;      //指向DIB的指针
     LPSTR    lpDIBBits;  // DIB像素指针
     DWORD    dwDIBSize;  //DIB大小
     
     HGLOBAL    m_hDib;//DIB对象的句柄
     CPalette* m_palDIB;//调色板指针
    };

    #endif // !defined(AFX_DIB_H__AC952C3A_9B6B_4319_8D6E_E7F509348A88__INCLUDED_)

    /////////////////////////////////////////////////////////////////////实现文件//////////////////////////////////////////////////////////////////////////////
    // Dib.cpp: implementation of the CDib class.
    //
    //////////////////////////////////////////////////////////////////////

    #include "stdafx.h"
    #include "Dib.h"

    #include <math.h>

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

    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    CDib::CDib()
    {
     InitMembers();
    }

    CDib::~CDib()
    {
     ClearMemory();
    }

    /*************************************************************************
     * 函数名称:ConstructPalette(HGLOBAL hDIB, CPalette* pPal)
     * 函数参数:
     *   HGLOBAL hDIB,DIB对象的句柄
     *   CPalette* pPal,调色板的指针
     * 函数类型:BOOL
     * 函数说明:该函数按照DIB创建一个逻辑调色板  
     ************************************************************************/

    BOOL CDib::ConstructPalette(HGLOBAL hDIB, CPalette* pPal)

     
     HANDLE hLogPal;// 逻辑调色板的句柄 
     int iLoop;// 循环变量 
     BOOL bSuccess = FALSE;// 创建结果 
     if (hDIB == NULL)//判断是否是有效的DIB对象
     {  
      return FALSE;// 返回FALSE
     } 
     lpdib = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);// 锁定DIB
     lpbminfo= (LPBITMAPINFO)lpdib;   
     long wNumColors =GetColorNum(lpdib);// 获取DIB中颜色表中的颜色数目 
     if (wNumColors != 0)
     {  
      hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)// 分配为逻辑调色板内存
             + sizeof(PALETTEENTRY)
             * wNumColors); 
      if (hLogPal == 0)// 如果失败则退出
      {   
       ::GlobalUnlock((HGLOBAL) hDIB);// 解除锁定   
       return FALSE;
      }  
      LPLOGPALETTE lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);  
      
      lpPal->palVersion = 0x300;// 设置调色板版本号    
      lpPal->palNumEntries = (WORD)wNumColors;// 设置颜色数目  
      for (iLoop=0; iLoop<(int)wNumColors;iLoop++)// 读取调色板
      {   
       lpPal->palPalEntry[iLoop].peRed =lpbminfo->bmiColors[iLoop].rgbRed;// 读取三原色分量      
       lpPal->palPalEntry[iLoop].peGreen =lpbminfo->bmiColors[iLoop].rgbGreen;       
       lpPal->palPalEntry[iLoop].peBlue =lpbminfo->bmiColors[iLoop].rgbBlue;        
       lpPal->palPalEntry[iLoop].peFlags =0;// 保留位   
      }  
      bSuccess=pPal->CreatePalette(lpPal);// 按照逻辑调色板创建调色板,并返回指针   
      ::GlobalUnlock((HGLOBAL) hLogPal);// 解除锁定    
      ::GlobalFree((HGLOBAL) hLogPal);// 释放逻辑调色板
     }  
     ::GlobalUnlock((HGLOBAL) hDIB);// 解除锁定  
     return bSuccess;// 返回结果
    }

    /*************************************************************************
     * 函数名称:GetBits(LPSTR lpdib)
     * 函数参数:
     *   LPSTR lpdib,指向DIB对象的指针
     * 函数类型:LPSTR 
     * 函数功能:计算DIB像素的起始位置,并返回指向它的指针
     ************************************************************************/

    LPSTR CDib::GetBits(LPSTR lpdib)
    {
     return (lpdib + ((LPBITMAPINFOHEADER)lpdib)->biSize+GetPalSize(lpdib));
    // return (lpdib + *(LPDWORD)lpdib+GetPalSize(lpdib));
    }

    /*************************************************************************
     * 函数名称:GetWidth(LPSTR lpdib)
     * 函数参数:
     *   LPSTR lpdib,指向DIB对象的指针
     * 函数类型:DWORD
     * 函数功能:该函数返回DIB中图象的宽度
     ************************************************************************/

    DWORD CDib::GetWidth(LPSTR lpdib)
    {
     return ((LPBITMAPINFOHEADER)lpdib)->biWidth;//返回DIB宽度
    }


    /*************************************************************************
     * 函数名称:GetHeight(LPSTR lpdib)
     * 函数参数:
     *   LPSTR lpdib ,指向DIB对象的指针
     * 函数类型:DWORD
     * 函数功能:该函数返回DIB中图象的高度
     ************************************************************************/


    DWORD CDib::GetHeight(LPSTR lpdib)
    {
     return ((LPBITMAPINFOHEADER)lpdib)->biHeight;//返回DIB高度

    }
    /*************************************************************************
     * 函数名称:GetPalSize(LPSTR lpdib)
     * 函数参数:
     *   LPSTR lpdib,指向DIB对象的指针
     * 函数类型:WORD
     * 函数功能:该函数返回DIB中调色板的大小
     ************************************************************************/

    WORD CDib::GetPalSize(LPSTR lpdib)

     return (WORD)(GetColorNum(lpdib) * sizeof(RGBQUAD));// 计算DIB中调色板的大小
    }

    /*************************************************************************
     * 函数名称:GetColorNum(LPSTR lpdib)
     * 函数参数:
     *   LPSTR lpdib,指向DIB对象的指针
     * 函数类型:WORD
     * 函数功能:该函数返回DIB中调色板的颜色的种数
     ************************************************************************/
    WORD CDib::GetColorNum(LPSTR lpdib)

     long dwClrUsed = ((LPBITMAPINFOHEADER)lpdib)->biClrUsed; // 读取dwClrUsed值 
     
     if (dwClrUsed != 0)
     {   
      return (WORD)dwClrUsed;// 如果dwClrUsed不为0,直接返回该值
     }
     else
     {
      dwClrUsed=(long)pow(2,24);
      return (WORD)dwClrUsed;
     }
    }

    /*************************************************************************
     * 函数名称:GetBitCount(LPSTR lpdib)
     * 函数参数:
     *   LPSTR lpdib,指向DIB对象的指针
     * 函数类型:WORD 
     * 函数功能:该函数返回DIBBitCount
     ************************************************************************/
    WORD CDib::GetBitCount(LPSTR lpdib)
    {
     return ((LPBITMAPINFOHEADER)lpdib)->biBitCount;// 返回位宽
    }


    /*************************************************************************
     * 函数名称:LoadFile(CFile& file)
     * 函数参数:
     *   CFile& file,要读取得文件文件CFile
     * 函数类型:HGLOBAL
     * 函数功能:将指定的文件中的DIB对象读到指定的内存区域中
     *************************************************************************/

    HGLOBAL CDib::LoadFile(CFile& file)
    {

     DWORD dwFileSize;
     
     dwFileSize= file.GetLength();//获取文件大小 
     if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))// 读取DIB文件头
     {  
      return NULL;// 大小不一致,返回NULL
     }
     // 如果文件类型不是"BM",其16进制值为0x4d42,则返回并进行相应错误处理
     if (bmfHeader.bfType !=0x4d42)
     {  
      return NULL;// 如果不是则返回NULL
     } 
     m_hDib= (HGLOBAL) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwFileSize-sizeof(BITMAPFILEHEADER));// 分配DIB内存
     if (m_hDib==NULL)
     {  
      return NULL;// 分配失败,返回NULL
     }
     /////////////////////////////////////////////////////////////////////////
     //给CDib类的成员变量赋值 
     lpdib = (LPSTR) ::GlobalLock((HGLOBAL) m_hDib);// 锁定 
     if (file.ReadHuge(lpdib, dwFileSize - sizeof(BITMAPFILEHEADER)) !=// 读像素
      dwFileSize - sizeof(BITMAPFILEHEADER) )//大小不一致
     {     
      ::GlobalUnlock((HGLOBAL) m_hDib); // 解除锁定   
      ::GlobalFree((HGLOBAL) m_hDib); // 释放内存
      return NULL;
     }  
     ::GlobalUnlock((HGLOBAL) m_hDib);// 解除锁定  
     return m_hDib;// 返回DIB句柄
    }

    /*************************************************************************
     * 函数名称:GetReqByteWidth(int bits)
     * 函数参数:
     *   int bits,位数
     * 函数类型:int
     * 函数功能:获取需要的行字节数,应为4的倍数
     *************************************************************************/
    int  CDib::GetReqByteWidth(int bits)
    {
     int getBytes=(bits + 31) / 32 * 4;
     return  getBytes;
    }

    /*************************************************************************
     * 函数名称:GetRectWidth(LPCRECT lpRect)
     * 函数参数:
     *   LPCRECT lpRect,指向矩形区域的指针
     * 函数类型:long
     * 函数功能:获取矩形区域的宽度
     *************************************************************************/

    long  CDib::GetRectWidth(LPCRECT lpRect)
    {
     long nWidth=lpRect->right - lpRect->left;
     return nWidth;
    }
    /*************************************************************************
     * 函数名称:GetRectHeight(LPCRECT lpRect)
     * 函数参数:
     *   LPCRECT lpRect,指向矩形区域的指针
     * 函数类型:long
     * 函数功能:获取矩形区域的高度
     *************************************************************************/
    long  CDib::GetRectHeight(LPCRECT lpRect)
    {
     long nHeight=lpRect->bottom - lpRect->top;
     return nHeight;
    }

    /*************************************************************************
     * 函数名称:InitMembers() 
     * 函数类型: void
     * 函数功能:初始化类的成员变量
     *************************************************************************/
    void CDib::InitMembers()
    {
     m_hDib=NULL;
     lpdib=NULL;
     lpDIBBits=NULL;
    }

    /*************************************************************************
     * 函数名称:ClearMemory() 
     * 函数类型: void
     * 函数功能:复位类的成员变量
     *************************************************************************/
    void CDib::ClearMemory()
    {
     if(m_hDib!=NULL)
      ::GlobalFree(m_hDib);
     lpdib=NULL;
    }

    /*************************************************************************
     * 函数名称:SaveFile(HGLOBAL hDib, CFile& file)
     * 函数参数:
     *   HGLOBAL hDib,要保存的DIB
     *   CFile& file,保存文件CFile
     * 函数类型:BOOL
     * 函数功能:将指定的DIB对象保存到指定的CFile中
     *************************************************************************/

    BOOL CDib::SaveFile(HGLOBAL hDib, CFile& file)
    {
     if (hDib == NULL)
     {  
      return FALSE;// 如果DIB为空,返回FALSE
     } 
     lpbmihrd = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);// 读取BITMAPINFO结构,并锁定 
     if (lpbmihrd == NULL)
     {  
      return FALSE;// 为空,返回FALSE
     }  
     bmfHeader.bfType ='BM'; // 填充文件头 
     dwDIBSize = *(LPDWORD)lpbmihrd + GetPalSize((LPSTR)lpbmihrd);// 文件头大小+颜色表大小   
     DWORD dwBmBitsSize;// 像素的大小  
     dwBmBitsSize =GetReqByteWidth((lpbmihrd->biWidth)*((DWORD)lpbmihrd->biBitCount)) * lpbmihrd->biHeight;// 大小为Width * Height  
     dwDIBSize += dwBmBitsSize;// 计算后DIB每行字节数为4的倍数时的大小
     lpbmihrd->biSizeImage = dwBmBitsSize;// 更新biSizeImage 
     bmfHeader.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);// 文件大小  
     bmfHeader.bfReserved1 = 0;// 两个保留字
     bmfHeader.bfReserved2 = 0;
     bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpbmihrd->biSize// 计算偏移量bfOffBits
           + GetPalSize((LPSTR)lpbmihrd);
     file.Write(&bmfHeader, sizeof(BITMAPFILEHEADER));// 写文件头    
     file.WriteHuge(lpbmihrd, dwDIBSize);// 写DIB头和像素
     
     ::GlobalUnlock((HGLOBAL) hDib);// 解除锁定 
     return TRUE;// 返回TRUE
    }

  • 相关阅读:
    20201015-3 每周例行报告
    20201008-1 每周例行报告
    20200924-1 每周例行报告
    20200924-3 单元测试,结对
    刷题-Leetcode-120. 三角形最小路径和
    刷题-Leetcode-1025. 除数博弈
    刷题-Leetcode-217. 存在重复元素
    刷题-Leetcode-24.两两交换链表中的节点
    刷题-AcWing-104. 货仓选址
    ARP报文抓包解析实验报告
  • 原文地址:https://www.cnblogs.com/humanchan/p/3046351.html
Copyright © 2020-2023  润新知