手机开发实战149——BMP介绍4

本文详细介绍了在手机开发中加载BMP图像的过程,包括加载文件头、位图信息头,行对齐计算,正确加载图像数据,并提供了GDI绘制图像的示例代码。内容涉及图像的宽、高、像素位数等关键属性,以及如何处理行对齐以确保数据正确读取。
摘要由CSDN通过智能技术生成

加载文件

  加载文件的目的是要得到图片属性,以及RGB数据,然后可以将其绘制在DC(GDI),或是生成纹理对象(3D:OpenGL/Direct3D)

1、加载文件头

  //Load the file header

  BITMAPFILEHEADER header;

  memset(&header, 0, sizeof(header));

  inf.read((char*)&header, sizeof(header));

  if(header.bfType != 0x4D42)

  return false;

  这个很简单,没有什么好说的。

2、加载位图信息头

  //Load the image information header

  BITMAPINFOHEADER infoheader;

  memset(&infoheader, 0, sizeof(infoheader));

  inf.read((char*)&infoheader, sizeof(infoheader));

  m_iImageWidth = infoheader.biWidth;

  m_iImageHeight = infoheader.biHeight;

  m_iBitsPerPixel = infoheader.biBitCount;

  这里我们得到了3各重要的图形属性:宽,高,以及每个像素颜色所占用的位数。

3、行对齐

  由于Windows在进行行扫描的时候最小的单位为4个字节,所以当

  图片宽 X 每个像素的字节数= 4的整数倍

  时要在每行的后面补上缺少的字节,以0填充(一般来说当图像宽度为2的幂时不需要对齐)。位图文件里的数据在写入的时候已经进行了行对齐,也就是说加载的时候不需要再做行对齐。但是这样一来图片数据的长度就不是:宽 X  X 每个像素的字节数了,我们需要通过下面的方法计算正确的数据长度:

  //Calculate the image data size

  int iLineByteCnt = (((m_iImageWidth*m_iBitsPerPixel) + 31) >> 5) << 2;

  m_iImageDataSize = iLineByteCnt * m_iImageHeight;

4、加载图片数据

  对于24位和32位的位图文件,位图数据的偏移量为sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER),也就是说现在我们可以直接读取图像数据了。

  if(m_pImageData) delete []m_pImageData;

  m_pImageData = new unsigned char[m_iImageDataSize];

  inf.read((char*)m_pImageData, m_iImageDataSize);

  如果你足够细心,就会发现内存m_pImageData里的数据的确是BGR格式,可以用个纯蓝色或者是纯红色的图片测试一下。

5、绘制

  好了,数据和属性我们都有了,现在就可以拿来随便用了,就和吃馒头一样,爱粘白糖粘白糖,爱粘红糖粘红糖。下面是GDI绘制代码,仅作参考:

  void CImage::DrawImage(HDC hdc, int iLeft, int iTop, int iWidth, int iHeight)

  {

  if(!hdc || m_pImageData == NULL)

  return;

  BITMAPINFO bmi;

  memset(&bmi, 0, sizeof(bmi));

  bmi.bmiHeader.biSize = sizeof(BITMAPINFO);

  bmi.bmiHeader.biWidth = m_iImageWidth;

  bmi.bmiHeader.biHeight = m_iImageHeight;

  bmi.bmiHeader.biPlanes = 1;

  bmi.bmiHeader.biBitCount = m_iBitsPerPixel;

  bmi.bmiHeader.biCompression = BI_RGB;

  bmi.bmiHeader.biSizeImage = m_iImageDataSize;

  StretchDIBits(hdc, iLeft, iTop, iWidth, iHeight,

  0, 0, m_iImageWidth, m_iImageHeight,

  m_pImageData, &bmi, DIB_RGB_COLORS, SRCCOPY);

  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值