位图(Bitmap)当然是最简单的,它Windows显示图片的基本格式,其文件扩展名为*.BMP。在Windows下,任何各式的图片文件(包括视频播放)都要转化为位图个时候才能显示出来,各种格式的图片文件也都是在位图格式的基础上采用不同的压缩算法生成的(Flash中使用了适量图,是按相同颜色区域存储的)。

一、下面我们来看看位图文件(*.BMP)的格式。

位图文件主要分为如下3个部分:

1、 文件信息头BITMAPFILEHEADER

结构体定义如下:

typedef struct tagBITMAPFILEHEADER { /* bmfh */

UINT bfType;
DWORD bfSize;
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;

} BITMAPFILEHEADER;

其中:

2、位图信息头BITMAPINFOHEADER

结构体定义如下:

typedef struct tagBITMAPINFOHEADER { /* bmih */

DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;

} BITMAPINFOHEADER;

其中:

3、RGB颜色阵列

有关RGB三色空间我想大家都很熟悉,这里我想说的是在Windows下,RGB颜色阵列存储的格式其实BGR。也就是说,对于24位的RGB位图像素数据格式是:

蓝色B值           绿色G值                           红色R值

对于32位的RGB位图像素数据格式是:

蓝色B值          绿色G值                           红色R值                         透明通道A值

透明通道也称Alpha通道,该值是该像素点的透明属性,取值在0(全透明)到255(不透明)之间。对于24位的图像来说,因为没有Alpha通道,故整个图像都不透明。

二、搞清了文件格式,下一步我们要实现加载。

加载文件的目的是要得到图片属性,以及RGB数据,然后可以将其绘制在DC上(GDI),或是生成纹理对象(3D:OpenGL/Direct3D)。这两种用途在数据处理上有点区别,我们主要按前一种用法讲,在和3D有不同的地方,我们再提出来。

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);

}

6、3D(OpenGL)的不同之处

如果你是想用刚才我们得到的数据生成纹理对象,那么你还要请出下面的问题。

首先,用来生成纹理的数据不需要对齐,也就是说不能在每行的后面加上对齐的字节。当然在OpenGL里要求纹理图片的尺寸为2的幂,所以这个问题实际上不存在;

其次,我们得到的图形数据格式是BGR(BGRA),所以在生成纹理的时候,需指定格式为GL_BGR_EXT(GL_BGRA_EXT);否则需要做BGR->RGB(BGRA->RGBA)的转化。

转载于:https://www.cnblogs.com/CZM-/p/5388553.html

bitmap格式分析相关推荐

  1. jpg分辨率格式 jpg格式分析(转)

    JPEG格式 格式:JFIF(JPEG档的交换格式) 压缩:JPEG(灰阶影像压缩比约为10:1:彩色影像约为20:1) 以JPEG文件格式保存的图像实际上是2个不同格式的混合物:JPEG格式规范本身 ...

  2. 【Android 安装包优化】资源混淆 ( resources.arsc 资源映射表混淆 | resources.arsc 资源映射表二进制格式分析 | 混淆全局字符串池和资源名称字符串池 )

    文章目录 一.resources.arsc 资源映射表 混淆 二.resources.arsc 资源映射表二进制格式分析 三.参考资料 资源混淆时 , 需要修改混淆 resources.arsc 资源 ...

  3. 【Android RTMP】RTMP 数据格式 ( FLV 视频格式分析 | 文件头 Header 分析 | 标签 Tag 分析 | 视频标签 Tag 数据分析 )

    文章目录 安卓直播推流专栏博客总结 一. RTMP 格式解析 二. 文件头 Header 分析 三. 标签 Tag 分析 四. 视频标签 Tag 数据分析 安卓直播推流专栏博客总结 Android R ...

  4. storm的消息格式分析

    storm的消息格式分析 @(STORM)[storm] storm的消息格式分析 一ITuple接口 二core-storm的消息格式 三trident的消息格式 一trident中tuple的基本 ...

  5. AAC ADTS格式分析

    AAC ADTS格式分析: 没有详细的参数说明,只有格式分析.可以查询文档查看详细参数说明. ADTS的全称是Audio Data Transport Stream.是AAC音频的传输流格 式.AAC ...

  6. 音视频开发(31)---H.264格式分析

    H.264格式分析 一.H.264基本流结构 H.264 的基本流(elementary stream,ES)的结构分为两层,包括视频编码层(VCL)和网络适配层(NAL).视频编码层负责高效的视频内 ...

  7. AVI视频格式分析-封装格式

    AVI视频封装格式分析 使用的工具 RIFF块 CHUNK块 LIST块 hdrl LIST avih CHUNK strl LIST strh CHUNK strf CHUNK JUNK CHUNK ...

  8. android本地图片转bitmap,Android中图片的网络路径转换为Bitmap格式

    在Android开发中,常常会需要将一张网络图片转换为Bitmap格式,为什么这样做呢,那是因为很多函数要求的是Bitmap类型的参数,所以直接传字符串进去是不行的,这时候就需要转换一下,源码如下: ...

  9. Android中Bitmap的分析与使用

    下面总结一下Bitmap的分析与使用 Bitmap的创建 创建Bitmap的时候,Java不提供new Bitmap()的形式去创建,而是通过BitmapFactory中的静态方法去创建,如:Bitm ...

最新文章

  1. 【Luogu P2764】最小路径覆盖问题
  2. 独家 | 麦肯锡教我的数据科学家的五大黄金法则
  3. python opencv cv.applyColorMap()函数(颜色映射)ColormapTypes【将Intel Realsense D435深度图的黑白图映射为彩色图】
  4. hadoop学习之:Map、Reduce详解
  5. 【转】Spark源码分析之-scheduler模块
  6. flink source 同步_大数据面试题-Flink
  7. Java中PO、DO、TO、DTO、 VO、 BO、POJO 、DAO的概念
  8. 网络(11)-什么是RestFul风格?
  9. header()函数使用说明
  10. 密码生成器--python
  11. 阿里云创新产品团队招聘!一大波岗位呼唤你
  12. 关于LM2596S-5.0电流声问题——输出电容选择
  13. opencore 引导 近完美 黑苹果EFI(技嘉H310/I5-9400F/RX560D)
  14. word如何弄成两竖列_word分栏后成了竖行
  15. eBay Android app 最新,ebay国际版app下载
  16. 生产注意事项(分片集群)
  17. B站Django项目天天生鲜学习|celery异步发送邮件遇到的问题
  18. 慧荣SM2246主控开卡一直处于Pretest状态解决方案
  19. win10 系统屏幕黑屏只有鼠标光标在动,问题解决
  20. CSDN 发布文章时 添加的图片 怎么 去掉水印

热门文章

  1. 让seo效果起死回生的妙招
  2. 慎用jQuery中的submit()方法
  3. Java线程面试题 Top 50(转)
  4. xHTML+div布局:三个div,两边div宽度固定,中间div宽度自适应
  5. Fort.js – 时尚、现代的表单填写进度提示效果
  6. Oracle ASM 11g新特性
  7. POJ_2001_Shortest Prefixes
  8. PE文件结构及其加载机制(三)
  9. 25个强大的 jQuery 砌体网页设计作品
  10. CSW是怎样用极端化来分裂BCH社区的