关于BMP文件的读取

http://hi.youkuaiyun.com/space-289256-do-album-id-85553.html  

要使用jpeg图片如上

想必大家对BMP文件的操作并不陌生,只是最近存在的一个问题让我百思不得其解,图片显示的颜色不对,而且出现了明显的倾斜现象,将该JPEG图片转为BMP图片,然后对其进行操作。在VC环境下使用的显示方式是调用DC的SetPixel方法。

 

如今已经得出了原因,是biSizeImage与图片的大小不一致产生的。现将代码分享如下,得出正确显示。

首先定义了数据结构

typedef struct BITMAP_FILE_TAG
        {
        BITMAPFILEHEADER bitmapfileheader;  // this contains the bitmapfile header
        BITMAPINFOHEADER bitmapinfoheader;  // this is all the info including the palette
        PALETTEENTRY     palette[256];      // we will store the palette here
        UCHAR            *buffer;           // this is a pointer to the data

        } BITMAP_FILE, *BITMAP_FILE_PTR;

 

读取位图的程序如下:


 

 CString StrFilter = "位图文件(*.bmp)|*.bmp|所有文件(*.*)|*.*||"; //filter file
 CFileDialog Dlg(TRUE,   //opendialog
     NULL,   //
     NULL,   //
     NULL,   //
     StrFilter,  //
     this);   //
 if (!Dlg.DoModal() == IDOK)  //
 {
  return;
 }
 CString StrFileName;
 StrFileName = Dlg.GetFileName();     
 
 //BITMAPINFO
 BITMAPINFO *pBmpInfo;
 //DIB
 BYTE* pBmpData;
 CFile MyFile;

 if (!MyFile.Open(StrFileName,CFile::modeRead|CFile::typeBinary))
 {
  return;
 }
 BITMAPFILEHEADER BmpHeader;   //fileheader
 if (MyFile.Read(&BmpHeader, sizeof(BmpHeader)) != sizeof(BmpHeader))
 {
  AfxMessageBox("read bimap file header failed");
  return;
 }
 if (BmpHeader.bfType != 0x4D42)   //'BM'
 {
  AfxMessageBox("not bitmap");
  return;
 }
 BITMAPINFOHEADER BmpInfo;   //infoheader
 if (MyFile.Read(&BmpInfo, sizeof(BmpInfo)) != sizeof(BmpInfo))
 {
  AfxMessageBox("read bimap info failed");
  return;
 }
 if (BmpInfo.biBitCount != 24)   //judge 24bit map
 {
  AfxMessageBox("not 24bit bitmap,ignored");
  return;
 }
 pBmpInfo = (BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER)]; //only use the bitmapinfoheader
                //palette not used,
                //cast bitmapinfoheader to bitmapinfo
 if (!pBmpInfo)
 {
  AfxMessageBox("memory allocate failed");
  return;
 }
 memcpy(pBmpInfo, &BmpInfo, sizeof(BITMAPINFOHEADER)); //cpy bmpinfo to the point pbmpinfo
 DWORD dataBytes = BmpHeader.bfSize - BmpHeader.bfOffBits; //bfsize:size of bimap file
 DWORD delta = (dataBytes/BmpInfo.biHeight - BmpInfo.biWidth*3);              //databytes:the pixels size
 pBmpData = (BYTE*)new char[dataBytes];
 if (!pBmpData)
 {
  AfxMessageBox("memory allocate failed");
  delete pBmpInfo;
  return;
 }
 if (MyFile.Read(pBmpData, dataBytes) != dataBytes)
 {
  AfxMessageBox("read bitmap data failed");
  delete pBmpInfo;
  delete pBmpData;
  return;

RGBTRIPLE *rgb;
 rgb = new RGBTRIPLE[BmpInfo.biWidth*BmpInfo.biHeight];

 MyFile.SeekToBegin();
 MyFile.Seek(BmpHeader.bfOffBits, CFile::begin);
 if (delta == 0)
 { 
  MyFile.Read(rgb,BmpInfo.biWidth*BmpInfo.biHeight*3);//read pixels from dataregion
 }
 else
 {
  for (WORD count=0;count<BmpInfo.biHeight;count++)
  {
   MyFile.Read(&rgb[count*BmpInfo.biWidth],BmpInfo.biWidth*3);
   MyFile.Seek(delta,CFile::current);
  }
 }
 MyFile.Close();
 CDC *pDC = GetDC();
 CRect rect;
 CBrush brush(RGB(255,255,255));
 GetClientRect(&rect);
 pDC->FillRect(&rect, &brush);
 if (BmpInfo.biCompression != BI_RGB)
 {
  AfxMessageBox("compressed bmp,no process");
  return;
 }

 


 }

 for (int i=0;i<BmpInfo.biHeight;i++) 

  for (int j=0;j<BmpInfo.biWidth;j++)
  {
    pDC->SetPixel(j, BmpInfo.biHeight-1-i,  
    RGB(rgb[i*BmpInfo.biWidth+j].rgbtRed, 
                    rgb[i*BmpInfo.biWidth+j].rgbtGreen, 
                    rgb[i*BmpInfo.biWidth+j].rgbtBlue));
   for (int k=0; k<1000; k++) ; //延时
  }

  delete pBmpInfo;
  delete pBmpData;
  delete rgb;

 

}

 

 

当然简单的方法也是有的,那就是调用StretchDIBits

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值