读取bmp图片的一部分

 

由于项目需要,bmp图片特别大有1G多,读取数据是只读取其中的一个窗口所以就根据网上的资料搞了下面这个c++的类。

 

class cReadBmp
{
 private:
  //图像的宽和高,行补足,头长度
  int m_fw,m_fh,m_att,m_hl;
  PBYTE m_bm;//像素数据
  PBYTE m_pvFile;//内存映射文件促使地址
  HANDLE m_hFileMapping;
 public:
  cReadBmp(LPCWSTR pfilename);
  ~cReadBmp(void);
 public:
  //获取图片宽度成功返回TRUE
  BOOL getPictureWidth(PINT pwidth);
  //获取图片高度成功返回TRUE
  BOOL getPictureHeight(PINT pheight);
  //获取图片的区域,失败返回NULL
  HBITMAP getBmpRect(int x,int y,int width,int height);
  //打开BMP文件
  BOOL openBmp(LPCWSTR pfilename);
  //关闭BMP文件
  BOOL closeBmp(void);
  //修正获取图像区域,返回TRUE表示已经修正过,否则表示没有修正过。
  BOOL fixRect(PINT px,PINT py,PINT pwidth,PINT pheight);
};

 

 

cReadBmp::cReadBmp(LPCWSTR pfilename)
{
 m_hFileMapping=NULL;
 openBmp(pfilename);
}

BOOL cReadBmp::openBmp(LPCWSTR pfilename)
{
 if(m_hFileMapping!=NULL)
 {
  closeBmp();
  m_hFileMapping=NULL;
 }

 //打开文件内核对象
 HANDLE hFile = CreateFile(pfilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    //如果打开文件失败则返回
 if (hFile == INVALID_HANDLE_VALUE)
    {
  CloseHandle(hFile);
  return FALSE;
    }
 
 //获取文件长度
 DWORD dwFileSize = GetFileSize(hFile, NULL);

 //映射文件视图
 m_hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, dwFileSize , NULL);
 CloseHandle(hFile);
 if (m_hFileMapping == NULL)
 {
  return FALSE;
 }

 //映射到进程地址空间
 m_pvFile = (PBYTE)MapViewOfFile(m_hFileMapping, FILE_MAP_READ, 0, 0, 0);
 if (m_pvFile == NULL)
 {
  CloseHandle(m_hFileMapping);
  return FALSE;
 }

 //BMP图片头长度
 memcpy(&m_hl,&m_pvFile[0xa],4);
 //BMP文件宽度
 memcpy(&m_fw,&m_pvFile[0x12],4);
 //BMP文件高度
 memcpy(&m_fh,&m_pvFile[0x16],4);
 //获取真实宽度
 m_att=(((m_fw*24)+31)>>5)<<2;

 //获取BMP图片的起始地址
 m_bm=&m_pvFile[m_hl];
 return TRUE;
}

BOOL cReadBmp::closeBmp(void)
{
 BOOL result=FALSE;
 if(m_hFileMapping!=NULL)
 {
  UnmapViewOfFile((LPCVOID)m_pvFile);
  CloseHandle(m_hFileMapping);
  result=TRUE;
 }
 m_pvFile=NULL;
 m_hFileMapping=NULL;
 return result;
}

cReadBmp::~cReadBmp(void)
{
 if(m_hFileMapping!=NULL)
  closeBmp();
}

BOOL cReadBmp::getPictureWidth(PINT pwidth)
{
 if(m_hFileMapping!=NULL)
 {
  
  *pwidth=m_fw;
  return TRUE;
 }
 return FALSE;
}

BOOL cReadBmp::getPictureHeight(PINT pheight)
{
 if(m_hFileMapping!=NULL)
 {
  *pheight=m_fh;
  return TRUE;
 }
 return FALSE;
}

HBITMAP cReadBmp::getBmpRect(int x,int y,int width,int height)
{
 if(m_hFileMapping==NULL)
  return NULL;

 HBITMAP result=NULL;
 int att;
 BITMAPINFOHEADER bmih;
 
 //生成返回数据快
 PBYTE pBits,pCurBits;

 fixRect(&x,&y,&width,&height); //获取窗口修正
 
 bmih.biSize                  = sizeof (BITMAPINFOHEADER) ;
 bmih.biWidth                 = width ;
 bmih.biHeight                = height ;
 bmih.biPlanes                = 1 ;
 bmih.biBitCount              = 24 ;
 bmih.biCompression           = BI_RGB ;
 bmih.biSizeImage             = 0 ;
 bmih.biXPelsPerMeter         = 0 ;
 bmih.biYPelsPerMeter         = 0 ;
 bmih.biClrUsed               = 0 ;
 bmih.biClrImportant          = 0 ;

 result=CreateDIBSection(NULL,(BITMAPINFO *)&bmih,DIB_RGB_COLORS, (void **)&pBits, NULL, 0);

 pCurBits=pBits;
 //宽度不足4的倍数的话要填满
 att=(((width*24)+31)>>5)<<2;
 for(int m=y;m<y+height;m++)
 {
  //if(m==5998)
   //DebugBreak();
  memcpy(pCurBits,&m_bm[m*m_att+x*3],width*3);
  pCurBits+=att;
 }
 
 return result;
}

BOOL cReadBmp::fixRect(PINT px,PINT py,PINT pwidth,PINT pheight)
{
 BOOL result=FALSE;

 if(m_hFileMapping==NULL)
  return result;

 *py = m_fh - *py - *pheight; //坐标轴调整

 if(*pwidth>m_fw)
 {
  *pwidth=m_fw;
  result=TRUE;
 }

 if(*pheight>m_fh)
 {
  *pheight=m_fh;
  result=TRUE;
 }

 if(*px<0)
 {
  *px=0;
  result=TRUE;
 }

 if(*py<0)
 {
  *py=0;
  result=TRUE;
 }

 if(*px+*pwidth>m_fw)
 {
    *px=m_fw-*pwidth;
    //*pwidth=m_fw-*px;
    result=TRUE;
 }

 if(*py+*pheight>m_fh)
 {
    *py=m_fh-*pheight;
  //*pheight=m_fh-*py
  result=TRUE;
 }

 return TRUE;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值