DIB类的封装

原文地址::http://blog.csdn.net/gao19900617/article/details/8098343


主要成员函数

1.构造函数

MyDib ( LPCTSTR  dibName);//从文件中读入DIB,参数dibName代表文件全路径名
MyDib ( CBitmap& ddb, CPalette* palette );//从DDB中获得DIB
MyDib ( int Width, int Height, int BitsPerPixel );//创建新的DIB

2.位图的显示

 int   StretchToDC ( CDC& dc, CRect& src, CRect& dst, DWORD rop = SRCCOPY );//在指定DC上缩放输出
 int   SetToDC ( CDC& dc, CRect& src, CPoint& dst ); //在指定DC上输出,不改变大小

3.BMP文件的存储

void  SaveDIB ( LPCTSTR dibName ); //保存位图,参数dibName代表文件全路径名

4.其它函数

 void*  GetBits();//返回像素数组
 int   GetBitsPerPixel ( ); //返回每个像素的位数
 long  GetWidth();  //获得图像的宽
 long  GetHeight();//获得图像的高
 long  BytesPerLine(); //获得图像每行扫描线所需的字节数
 CPalette* GetPalette(); //获得调色板
 void  CopyPalette(CPalette&); //复制调色板
 int GetPaletteCount(); //获得调色板的大小
 long  GetBodySize(); //获得像素数组的大小

头文件

[cpp]  view plain copy
  1. #pragma once  
  2.   
  3. class MyDib : public CObject  
  4. {  
  5.  /*成员变量*/  
  6. private:  
  7.  //DIB文件  
  8.  BITMAPINFO* DibInfo;  
  9.  //像素数组  
  10.  void*  DibBits;   
  11.   
  12.  /*成员函数*/  
  13. public:  
  14.   
  15.  //构造函数  
  16.  MyDib ( LPCTSTR  dibName);//从文件中读入DIB,参数dibName代表文件全路径名  
  17.  MyDib ( CBitmap& ddb, CPalette* palette );//从DDB中获得DIB  
  18.  MyDib ( int Width, int Height, int BitsPerPixel );//创建新的DIB  
  19.   
  20.  //析构函数  
  21.  ~MyDib ( );  
  22.   
  23.  //返回像素数组  
  24.  void*  GetBits();  
  25.  //返回每个像素的位数  
  26.  int   GetBitsPerPixel ( );  
  27.  //获得图像的高  
  28.  long  GetWidth();  
  29.  //获得图像的宽  
  30.  long  GetHeight();  
  31.  //获得图像每行扫描线所需的字节数  
  32.  long  BytesPerLine();  
  33.  //获得调色板  
  34.  CPalette* GetPalette();  
  35.  //复制调色板  
  36.  void  CopyPalette(CPalette&);  
  37.  //获得调色板的大小  
  38.  int GetPaletteCount();  
  39.  //获得像素数组的大小  
  40.  long  GetBodySize();  
  41.  //在指定DC上缩放输出  
  42.  int   StretchToDC ( CDC& dc, CRect& src, CRect& dst, DWORD rop = SRCCOPY );  
  43.  //在指定DC上输出,不改变大小  
  44.  int   SetToDC ( CDC& dc, CRect& src, CPoint& dst );  
  45.  //保存位图,参数dibName代表文件全路径名  
  46.  void  SaveDIB ( LPCTSTR dibName );  
  47. };  

 

源文件

[cpp]  view plain copy
  1. // MyDib.cpp : 实现文件  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "MyDib.h"  
  6.   
  7.   
  8. MyDib::MyDib ( LPCTSTR dibName )  
  9. : DibBits ( NULL ), DibInfo ( NULL )  
  10. {  
  11.  //创建CFile对象  
  12.  CFile fp ( dibName, CFile::modeRead | CFile::typeBinary );  
  13.   
  14.  BITMAPFILEHEADER bmfileheader;  
  15.  BITMAPINFOHEADER bmheader;  
  16.   
  17.  ULONGLONG headpos;  
  18.  int PaletteSize = 0;  
  19.  int ret, cbHeaderSize;  
  20.  //获取文件指针的位置  
  21.  headpos = fp.GetPosition();  
  22.  //读取BMP文件头  
  23.  ret = fp.Read ( &bmfileheader, sizeof(BITMAPFILEHEADER) );  
  24.  //如果文件类型标头不是“0x4d42”,表示该文件不是BMP类型文件  
  25.  //则提示错误并退出。注意“0x4d42”的字符意义就是“BM”  
  26.  if ( bmfileheader.bfType != 0x4d42)   
  27.  {  
  28.   AfxMessageBox(L"Error!");  
  29.   return;  
  30.  }  
  31.   
  32.  //读取BMP文件信息头   
  33.  ret = fp.Read ( &bmheader, sizeof(BITMAPINFOHEADER) );  
  34.  //计算RGBQUAD的大小  
  35.  switch ( bmheader.biBitCount )  
  36.  {  
  37.  case 1:  
  38.   PaletteSize = 2;  
  39.   break;  
  40.  case 4:  
  41.   PaletteSize = 16;  
  42.   break;  
  43.  case 8:  
  44.   PaletteSize = 256;  
  45.   break;  
  46.  }  
  47.   
  48.  //为BITMAPINFO结构分配内存  
  49.  cbHeaderSize = sizeof(BITMAPINFOHEADER) + PaletteSize*sizeof ( RGBQUAD );  
  50.  DibInfo = (BITMAPINFO*) new char [ cbHeaderSize ];  
  51.  DibInfo->bmiHeader = bmheader;  
  52.   
  53.  if ( PaletteSize )  
  54.  {   
  55.   ret = fp.Read ( &(DibInfo->bmiColors[0]), PaletteSize*sizeof ( RGBQUAD ) );  
  56.   if ( ret != int( PaletteSize*sizeof ( RGBQUAD ) ) )  
  57.   {  
  58.    delete[] DibInfo;  
  59.    DibInfo = NULL;  
  60.    return;  
  61.   }  
  62.  }  
  63.   
  64.  //为像素数组分配空间,大小由GetBodySize()决定  
  65.  DibBits = (void*) new char[GetBodySize()];  
  66.  //把文件指针移动到DIB图像数组  
  67.  fp.Seek ( headpos + bmfileheader.bfOffBits, CFile::begin );  
  68.   
  69.  ret = fp.Read ( DibBits, GetBodySize() );  
  70.  if ( ret != int ( GetBodySize() ) )  
  71.  {  
  72.   delete[] DibInfo;  
  73.   delete[] DibBits;  
  74.   DibInfo = NULL;  
  75.   DibBits = NULL;  
  76.  }  
  77.  //关闭文件  
  78.  fp.Close();  
  79. }  
  80.   
  81. MyDib::MyDib ( CBitmap& ddb, CPalette* palette )  
  82. : DibBits ( NULL ), DibInfo ( NULL )  
  83. {  
  84.  BITMAP ddbinfo;  
  85.  //获得DDB的相关信息  
  86.  ddb.GetBitmap ( &ddbinfo );   
  87.  /*下面根据图像的高度宽度等信息,填写DIB所必需的BITMAPINFO*/  
  88.  int w = ddbinfo.bmWidth;  
  89.  int h = ddbinfo.bmHeight;  
  90.  int BitsPerPixel = ddbinfo.bmPlanes*ddbinfo.bmBitsPixel;  
  91.   
  92.  int i;  
  93.  int PaletteSize = 0, cbHeaderSize;  
  94.   
  95.  //根据每像素需要几个bit来设置RGBQUAD数组的大小  
  96.  switch ( BitsPerPixel )   
  97.  {  
  98.  case 1:  
  99.   PaletteSize = 2;  
  100.   break;  
  101.  case 4:  
  102.   PaletteSize = 16;  
  103.   break;  
  104.  case 8:  
  105.   PaletteSize = 256;  
  106.   break;  
  107.   //超过8位的DIB不需要调色板  
  108.  case 15:  
  109.  case 16:  
  110.   BitsPerPixel = 16;  
  111.   break;  
  112.  }  
  113.   
  114.  cbHeaderSize = sizeof(BITMAPINFOHEADER) + PaletteSize * sizeof ( RGBQUAD );  
  115.  if ( DibInfo ) delete[] DibInfo;  
  116.  //为BITMAPINFO的对象DibInfo分配一段内存空间  
  117.  DibInfo = (BITMAPINFO*) new char [ cbHeaderSize ];   
  118.  //填写BITMAPINFO  
  119.  DibInfo->bmiHeader.biSize = sizeof ( BITMAPINFOHEADER );  
  120.  DibInfo->bmiHeader.biWidth = w;  
  121.  DibInfo->bmiHeader.biHeight = h;  
  122.  DibInfo->bmiHeader.biPlanes = 1;  
  123.  DibInfo->bmiHeader.biBitCount = short(BitsPerPixel);  
  124.  DibInfo->bmiHeader.biCompression = BI_RGB;  
  125.  DibInfo->bmiHeader.biSizeImage = BytesPerLine() * DibInfo->bmiHeader.biHeight;  
  126.  DibInfo->bmiHeader.biXPelsPerMeter =  
  127.   DibInfo->bmiHeader.biYPelsPerMeter = 3780;  
  128.  DibInfo->bmiHeader.biClrUsed = PaletteSize;  
  129.  DibInfo->bmiHeader.biClrImportant = PaletteSize;  
  130.   
  131.  if ( PaletteSize )  
  132.  {  
  133.   //把RGBQUAD数组中的每个元素全部置0  
  134.   for ( i = 0 ; i < PaletteSize ; i ++ )  
  135.   {  
  136.    DibInfo->bmiColors[i].rgbRed = 0;  
  137.    DibInfo->bmiColors[i].rgbGreen = 0;  
  138.    DibInfo->bmiColors[i].rgbBlue = 0;  
  139.    DibInfo->bmiColors[i].rgbReserved = 0;  
  140.   }  
  141.  }  
  142.   
  143.  //为DIB像素数组分配空间,大小由GetBodySize()决定  
  144.  DibBits = (void*) new char[GetBodySize()];  
  145.  //判断是否由调色板,如果有则将palette中的entry  
  146.  //复制到BITMAPINFO的RGBQUAD数组中  
  147.  if ( palette ) CopyPalette ( *palette );  
  148.   
  149.  // 将DDB中的图像信息复制到DIB中  
  150.  // GetDesktopWindow()返回桌面窗口的句柄  
  151.  CWnd DesktopWnd;   
  152.  DesktopWnd.Attach ( ::GetDesktopWindow() );  
  153.  CWindowDC dtpDC ( &DesktopWnd );  
  154.  // 完成从DDB向DIB的转换工作  
  155.  ::GetDIBits( dtpDC.m_hDC,    
  156.   HBITMAP ( ddb ),    
  157.   0,      
  158.   ddbinfo.bmHeight,   
  159.   LPVOID ( DibBits ),   
  160.   DibInfo,  
  161.   DIB_RGB_COLORS    
  162.   );  
  163.  DesktopWnd.Detach();  
  164. }  
  165.   
  166. MyDib::~MyDib()  
  167. {  
  168.  delete[] DibInfo;  
  169.  delete[] DibBits;  
  170. }  
  171.   
  172. void* MyDib::GetBits()   
  173. {  
  174.  return DibBits;   
  175. }  
  176.   
  177. int MyDib::GetBitsPerPixel ()   
  178. {   
  179.  if( !DibInfo )return 0;  
  180.  return DibInfo->bmiHeader.biBitCount;   
  181. }  
  182.   
  183. long MyDib::GetWidth()   
  184. {   
  185.  return DibInfo->bmiHeader.biWidth;   
  186. }  
  187.   
  188. long MyDib::GetHeight()   
  189. {   
  190.  return DibInfo->bmiHeader.biHeight;   
  191. }  
  192.   
  193. long MyDib::GetBodySize()   
  194. {   
  195.  return BytesPerLine() * DibInfo->bmiHeader.biHeight;   
  196. }  
  197.   
  198. int MyDib::GetPaletteCount()  
  199. {  
  200.  int PaletteSize = 0;  
  201.  if (!DibInfo) return 0;  
  202.  switch ( DibInfo->bmiHeader.biBitCount )  
  203.  {  
  204.  case 1:  
  205.   PaletteSize = 2;  
  206.   break;  
  207.  case 4:  
  208.   PaletteSize = 16;  
  209.   break;  
  210.  case 8:  
  211.   PaletteSize = 256;  
  212.   break;  
  213.  }  
  214.  return PaletteSize;  
  215. }  
  216.   
  217. long MyDib::BytesPerLine()   
  218. {   
  219.  return ((((DibInfo->bmiHeader.biWidth * GetBitsPerPixel())+31)/32)*4);  
  220. }  
  221.   
  222. int MyDib::SetToDC ( CDC& dc, CRect& src, CPoint& dst )  
  223. {  
  224.  return ::SetDIBitsToDevice(  
  225.   dc.m_hDC,   
  226.   dst.x,   
  227.   dst.y,    
  228.   src.Width(),    
  229.   src.Height(),    
  230.   src.left,    
  231.   src.top,    
  232.   0,    
  233.   DibInfo->bmiHeader.biHeight,    
  234.   DibBits,    
  235.   DibInfo,    
  236.   DIB_RGB_COLORS    
  237.   );   
  238. }  
  239.   
  240. int MyDib::StretchToDC ( CDC& dc, CRect& src, CRect& dst, DWORD rop )  
  241. {  
  242.  return ::StretchDIBits (  
  243.   dc.m_hDC,   
  244.   dst.left,    
  245.   dst.top,    
  246.   dst.Width(),    
  247.   dst.Height(),    
  248.   src.left,    
  249.   src.top,    
  250.   src.Width(),    
  251.   src.Height(),    
  252.   DibBits,    
  253.   DibInfo,   
  254.   DIB_RGB_COLORS,    
  255.   rop    
  256.   );   
  257. }  
  258.   
  259. void MyDib::SaveDIB ( LPCTSTR dibName )  
  260. {  
  261.  //若DIB为空则提示错误并返回  
  262.  if(!DibInfo)  
  263.  {  
  264.   AfxMessageBox(L"DIB信息不存在!");  
  265.   return;  
  266.  }  
  267.   
  268.  //通过文件名创建CFile对象  
  269.  //若文件打开失败则提示错误并返回  
  270.  CFile file;  
  271.  if(!file.Open(dibName, CFile::modeCreate | CFile::modeReadWrite))  
  272.  {  
  273.   AfxMessageBox(L"建立文件失败!");  
  274.   return;  
  275.  }  
  276.   
  277.  //Bitmap文件头  
  278.  BITMAPFILEHEADER bmfileheader;  
  279.   
  280.  long size = BytesPerLine() * DibInfo->bmiHeader.biHeight;  
  281.  int PaletteSize = GetPaletteCount();  
  282.   
  283.  //填写BMP文件的数据  
  284.  bmfileheader.bfType = 0x4d42;//类型表示"BM"  
  285.  bmfileheader.bfReserved1 = bmfileheader.bfReserved2 = 0;//保留字0  
  286.  bmfileheader.bfOffBits =   
  287.   sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)  
  288.   +PaletteSize*sizeof( RGBQUAD );  
  289.  bmfileheader.bfSize = bmfileheader.bfOffBits + size;  
  290.   
  291.  //将文件头,位图信息和像素数组写入磁盘文件  
  292.  file.Write ( &bmfileheader, sizeof(BITMAPFILEHEADER) );  
  293.  file.Write ( DibInfo, sizeof(BITMAPINFOHEADER)+PaletteSize*sizeof( RGBQUAD ) );  
  294.  file.Write ( DibBits, size );  
  295.  //关闭文件  
  296.  file.Close();   
  297. }  
  298.   
  299. void MyDib::CopyPalette( CPalette& palette )  
  300. {  
  301.  int i;  
  302.  PALETTEENTRY *pe;  
  303.   
  304.  if ( !DibInfo->bmiHeader.biBitCount ) return;  
  305.  if ( palette.GetEntryCount() != DibInfo->bmiHeader.biBitCount ) return;  
  306.   
  307.  pe = new PALETTEENTRY[palette.GetEntryCount()];  
  308.  palette.GetPaletteEntries( 0, palette.GetEntryCount(), pe );  
  309.   
  310.  for ( i = 0 ; i < palette.GetEntryCount() ; i ++ )  
  311.  {  
  312.   DibInfo->bmiColors[i].rgbRed = pe[i].peRed;  
  313.   DibInfo->bmiColors[i].rgbGreen = pe[i].peGreen;  
  314.   DibInfo->bmiColors[i].rgbBlue = pe[i].peBlue;  
  315.   DibInfo->bmiColors[i].rgbReserved = 0;  
  316.  }  
  317.   
  318.  delete[] pe;  
  319. }  



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值