⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dibapi.cpp

📁 这个程序是用来实现关于(bmp)文件的读写功能。很简单
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		  //对于Windows 3.0 DIB 返回lpbmi->biHeight
		  return lpbmi->biHeight;

	  }
	  else
	  {

		  //对于其他格式的DIB,返回lpbmc->bcHeight
		  return lpbmc->bcHeight;

	  }

  }



  /************************************************************************************************************
   *function:
   *	PaletteSize()
   *
   *parameter:
   *	LPSTR lpbi				-指向DIB 图像的指针
   *
   *return:
   *	WORD					-DIB 图像中调色板的大小
   *
   *comments:
   *	该函数返回DIB中的调色板的大小。对于Windows 3.0 DIB ,返回颜色数目*
   *RGBQUAD的大小;对于其他返回颜色数目*RGBTRIPLE的大小。
   *
   ************************************************************************************************************/



  WORD WINAPI PaletteSize(LPSTR lpbi)
  {

	  //计算DIB中调色板的大小
	  if(IS_WIN30_DIB(lpbi))
	  {

		  //返回 颜色数目*RGBQUAD的大小
		  return (WORD)(::DIBNumColors(lpbi)*sizeof(RGBQUAD));

	  }
	  else
	  {

		  //返回 颜色数目*RGBTRIPLE的大小
		  return (WORD)(::DIBNumColors(lpbi)*sizeof(RGBTRIPLE));
   
	  }

  }



  /**************************************************************************************************************
   *function:
   *	DIBNumColors()
   *
   *parameter:
   *	LPSTR lpbi					-指向DIB对象的指针
   *
   *return:
   *	WORD						-返回调色板中颜色的种数
   *
   *comments:
   *	该函数返回DIB 中调色板的颜色的种数。对于单色位图,返回2;
   *对于16色位图,返回16;对于256色位图,返回256;对于真彩色位图(24位),没有调色板的,返回0.
   *
   *************************************************************************************************************/




  WORD WINAPI DIBNumColors(LPSTR lpbi)
  {

	  DWORD wBitCount;

	  /*
	  对于Windows 3.0 DIB,实际颜色的数目可以比位数的数目要小
	  对于这种情况,则返回一个近似数。
	  */


	  //判断是否是WIN3.0 DIB
	  if(IS_WIN30_DIB(lpbi))
	  {

		  DWORD dwClrUsed;

		  //读取dwClrUsed值
		  dwClrUsed=((BITMAPINFOHEADER)lpbi)->biClrUsed;

		  if(dwClrUsed !=0)
		  {

			  //如果dwClrUsed (实际用到的颜色数)不为0,直接返回改值
			  return (WORD)dwClrUsed;

		  }

	  }


	  //读取像素的位数
	  if(IS_WIN30_DIB(lpbi))
	  {

		  //读取biBitCount值
		  wBitCount=((LPBITMAPINFOHEADER)lpbi)->biBitCount;

	  }
	  else
	  {

		  //读取bcBitCount值
		  wBitCount=((LPBITMAPCOREHEADER)lpbi)->bcBitCount;

	  }

	  //按照像素的位数计算颜色数目
	  switch(wBitCount)
	  {

	  case 1:
		  return 2;

	  case 4:
		  return 16;

	  case 8:
		  return 256;

	  default:
		  return 0;

	  }

  }





  /************************************************************************************************************
   *
   *funtion:
   *	CopyHandle()
   *
   *parameter:
   *	HGLOBAL h				-要复制的内存区域
   *
   *return:
   *	HGOBAL					-复制后的新内存区域
   *
   *comments:
   *	该参数复制指定的内存区域。返回复制后的新内存区域,出错时返回0.
   *
   ****************************************************************************************************************/



  HGLOBAL WINAPI CopyHandle(HGLOABAL h)
  {

	  if(h==NULL)
		  return NULL;

	  // 获取指定内存区域的大小
	  DWORD dwLen=::GlobalSize((HGLOBAL)h);


	  //分配新内存空间
	  HGLOBAL hCopy=::GlobalAlloc(GHND,dwLen);

	  //判断分配是否成功
	  if(hCopy!=NULL)
	  {

		  //Lock
		  void *lpCopy=::GlobalLock((HGLOBAL) hCopy);
		  void *lp	=::GlobalLock((HGLOBAL) h);

		  //Copy
		  memcpy(lpCopy,lp,dwLen);

		  //解除锁定
		  ::GlobalUnlock(hCopy);
		  ::GlobalUnlock(h);

	  }
	  
	  return hCopy;

  }





  /**************************************************************************************************************
   *function:
   *	SaveDIB()
   *
   *parameter:
   *	HDIB hDib
   *	CFile& file
   *
   *return:
   *	BOOL
   *
   *comments:
   *	该函数指定的DIB对象保存到指定的CFile中。该CFile由调用程序打开和关闭。
   *
   *****************************************************************************************************************/



  BOOL WINAPI SaveDIB(HDIB hDib,CFile& file)
  {

	  //Bitmap 文件头
	  BITMAPFILEHEADER bmfHdr;

	  //指向BIPMAPINFOHEADER的指针
	  LPBITMAINFOHEADER lpBI;

	  //DIB 的大小
	  DWORD dwDIBSize;

	  if(hDib==NULL)
	  {

		  return FALSE;

	  }

	  //读取BITMAPINFO结构,并锁定
	  lpBI=(LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);

	  if(lpBI==NULL)
	  {

		  return FALSE;

	  }
	   
	  if(!IS_WIN30_DIB(lpBI))
	  {

		  ::GlobalUnlock((HGLOBAL)hDib);

		  return FALSE;	

	  }

	  //填充文件头

	  //文件类型“BM”
	  bmfHdr.bfType=DIB_HEADER_MARKER;

	  /*计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并不是DIB 的真正的大小,
	   *它总是多几个字节。这样就需要计算一下DIB 的真实大小。
	   *
	   *文件头大小+颜色表大小
	   *(BITMAPINFOHEADER和BIPMAPCOREHEADER结构的第一个DWORD都是改结构的大小)*/

	  dwDIBSize=*(LPDWORD)lpBI+::PaletteSize(LPSTR)lpBI);

	  //计算图像的大小
	  if((lpBI->biCompression==BI_RLE8)||(lpBI->biCompression==BI_RLE4))
	  {

		  //对于RLE位图,没法计算大小,只能信任biSizeImage内的值
		  dwDIBSize+=lpBI->biSizeImage;

	  }
	  else
	  {

		  DWORD dwBmBitsSize;

		  //大小为Width*Height
		  dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))*lpBI->biHeight;

		  //计算DIB真正的大小
		  dwDIBSize+=dwBmBitsSize;

		  //更新biSizeImage(很多BMP文件头中的biSizeImage的值是错误的)
		  lpBI->biSizeImage=dwBmBitsSize;

	  }

	  //计算文件大小,DIB(大小)+BIPMAPFILEHEADER结构的大小
	  bmfHdr.bfSize=dwDIBSize+sizeof(BITMAPFILEHEADER);

	  //两个保留字
	  bmfHdr.bfReserved1=0;
	  bmfHdr.bfReserved2=0;

	  //计算偏移量bfOffBits
	  bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+lpBI->biSize
														+PaletteSize((LPSTR)lpBI);

	  //尝试写文件
	  TRY
	  {

		  //些写件头
		  file.Write((LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER));

		  //写DIB头和像素
		  file.WriteHuge(lpBI,dwDIBSize);

	  }
	  CATCH(CFileException, e)
	  {

		  ::GlobalUnlock((HGLOBAL)hDib);

		  THROW_LAST();

	  }
	  END_CATCH
	  
	  ::GlobalUnlock((HGLOBAL)hDib);

	  return TRUE;

  }
  





  /**************************************************************************************************************
   *
   *function:
   *	ReadDIBFile()
   *
   *parameter:
   *	CFile& file
   *
   *return:
   *	HDIB
   *
   *comment:
   *	该函数将指定的文件的DIB对象读到指定的区域中,除BIPMAPFILEHEADER
   *外的内容都将被读入内存。
   *
   ************************************************************************************************************/



   HDIB WINAPI ReadDIBFile(CFile& file)
   {

	   BITMAPFILEHEADER bmfHdr;
	   DWORD dwBitsSize;
	   HDIB hDIB;
	   LPSTR pDIB;

	   //获取DIB(文件)长度
	   dwBitsSize=file.GetLength();

	   //尝试读取DIB文件头
	   if(file.Read((LPSTR)&bmfHdr,sizeof(bmfHdr))!=sizeof(BITMAPFILEHEADER))
	   {
		   //大小不对,返回NULL
		   return NULL;
	   }
	   //判断是否是DIB的对象,检查头俩个字节是不是“BM”
	   if(bmfHdr.bfType!=DIB_HEADER_MARKER)
	   {
		   //非DIB对象,返回NULL
		   return NULL;
	   }

	   //为DIB分配内存
	   hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,dwBitsSize);
	   if(hDIB==0)
	   {
		   //内存分配失败,返回NULL
		   return NULL;
	   }
	   pDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);

	   if(file.ReadHuge(pDIB,dwBitsSize-sizeof(BIPMAPFILEHEADER))!=dwBitsSize-sizeof(BITMAPFILEHEADER))
	   {
		   //对象不对


		   ::GlobalUnlock((HGLOBAL)hDIB);

		   ::GolbalFree((HGLOBAL)hDIB);

		   return NULL;

	   }
	   ::GlobalUnlock((HGLOBAL)hDIB);

	   return hDIB;
	   
   }








⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -