BMP说明

BMP是BitMap的缩写,即位图,是一种非压缩格式,图像文件一般比较大,Windows系统内部各图像绘制操作都是以BMP为基础的。

BMP图像组成

BMP文件由四部分:

  1. 文件头信息,固定大小,结构体见BitmapFileHeader
  2. 图像信息头,固定大小,结构见BitmapInfoHeader
  3. 调色板,可选的,大小根据不同位数不同。
  4. 位图RGB数据,大小可以根据位数,高宽计算出来。

BMP数据结构

typedef unsigned short U16;
typedef unsigned long  U32;typedef struct tagBitmapFileHeader
{U16 bfType;         /* windows下该值必需是0x4D42,即字符'BM'*/U32 bfSize;         /* bmp文件大小,包含bmp文件头,信息头,调色板大小,数据大小 */U16 bfReserved1;    /* 保留,必须设置为0 */U16 bfReserved2;    /* 保留,必须设置为0 */U32 bfOffBits;      /* rgb数据相对文件头偏移量 */
} BitmapFileHeader;typedef struct
{U32 biSize;         /* 信息头大小sizeof(BitmapInfoHeader) */U32 biWidth;        /* 图象的宽度,以象素为单位 */U32 biHeight;       /* 图象的高度,以象素为单位,正值倒向位图,负值正向位图 */U16 biPlanes;       /* 位面数,设为1 */U16 biBitCount;     /* 位图位数,可以为32,24,16,8,4,1 */U32 biCompression;  /* 说明图象数据压缩的类型,BI_RGB(0) BI_BITFIELDS(3)等 */U32 biSizeImage;    /* 图像数据大小,包括位图信息大小和数据大小 */        U32 biXPelsPerMeter;/* 水平分辨率,一般可填0 */    U32 biYPelsPerMeter;/* 垂直分辨率,一般可填0*/U32 biClrUsed;      /* 颜色索引使用数,一般填0,表示都使用 */U32 biClrImportant; /* 重要颜色索引数,一般填0,表示都重要 */
} BitmapInfoHeader;

数据长度计算:
int iLineByteCnt = (((biWidth*biBitCount) + 31) >> 5) << 2;
iRGBDataSize = iLineByteCnt * biHeight;
这个公式主要做了数据行4字节对齐工作,先加31右移5位(除32)做对齐工作,左移2(乘4)转成字节。

biBitCount与biCompression
24位色与32位色biBitCount分部为24及32,biCompression固定为BI_RGB,一个像素占用3个及4个字节. 
16位色,biBitCount为16,每个像素占用2个字节,为表示2个字节RGB的位置,分为多种情况

  • biCompression为BI_RGB时,表明为RGB555格式,最高位为0,RGB各占5位,这种16位色格式无调色板信息。
  • biCompression为BI_BITFIELDS时,则表明使用掩码方式,BitmapInfoHeader后面12字节(3个int)分别为RGB的掩码,555格式下,掩码为0x7C00、0x03E0、0x001F,565格式下,它们则分别为:0xF800、0x07E0、0x001F,掩码方式挺灵活,甚至都可以自己定义16位色格式如RGB844,当然意义不大。

BMP数据结构比较简单,调试板信息是可变项,其他都是固定的,较易处理, 有几个地方需要注意:

  • BitmapFileHeader结构不是4字节对齐,需注意使用#pragma pack(2)或__attribute__((aligned(2)))方式进行2直接对齐。
  • BMP图片存储时RGB数据时行一般是倒序的,填充的时候注意倒序填充。

BMP转YUV

YUV和BMP都是非压缩格式,不存在解码过程,只需要做像素点到像素点的转换,YUV转bmp公式较多,应用到不同场景,下面是ITU-R BT.601建议在数字视频领域使用的公式(带有伽马校正,图像增强效果):

R' = 1.164*(Y’-16) + 1.596*(Cr'-128)
G' = 1.164*(Y’-16) - 0.813*(Cr'-128) - 0.392*(Cb'-128)
B' = 1.164*(Y’-16) + 2.017*(Cb'-128)

效果肯定是最好的,但运算量也是最大的,如果在嵌入式设备上使用,可以使用下面的简化公式:

R = Y + 1.4075 *(V-128)
G = Y – 0.3455 *(U –128) – 0.7169 *(V –128)
B = Y + 1.779 *(U – 128)

在代码中实现该公式时,为提高计算效率,浮点运算需转为整形运算,公式可以转化为如下形式(统一先左移20,再右移20):

R = (Y<<20 + 1475871 *(V-128)) >> 20
G = (Y<<20 – 362283 *(U –128) – 751724 *(V –128)) >> 20
B = (Y <<20 + 1865417 *(U – 128)) >> 20

由于YUV每个分量都使用1个字节来存储(YUV420格式UV分量会重复使用),每个值的取值范围为(0~255),为减少乘法运算,可以把乘法部分用局部查表法实现,如下:

int V1475871[256] = {0};
int V751724[256] = {0};
int U362283[256] = {0};
int U1865417[256] = {0};for (i = 0; i < 256; i++)
{V1475871[i] = (i - 128) * 1475871;V751724[i] = (i - 128) * 751724;U362283[i] = (i - 128) * 362283;U1865417[i] = (i - 128) * 1865417;
}/* 使用局部查表法,公式转成如下形式: */
R = (Y<<20 + V1475871[V]) >> 20;
G = (Y<<20 – U362283[U] – V751724[V]) >> 20;
B = (Y <<20 + U1865417[U]) >> 20;

24位色及32位色一般采用局部查表法优化效率,采用完全查表法内存使用代价太大,如果16位色,则可以采用完全查表法。
局部查表法优化了乘法操作,优化效果有限(多个平台测试结果都在10%左右)。

测试程序

下面是一个yuv420转bmp的小测试程序,包含yuv420p转bmp8888,bmp888,bmp1555,bmp565这几种格式,工具和源码地址:

http://download.csdn.net/detail/t3swing/9909075

测试工程为vs2008,测试代码效率并非最优,尤其使用了函数指针,降低了10%左右的转换速度,大家可以参考并优化。

yuv转bmp说明2相关推荐

  1. Androd Camera Yuv Jepg bmp

    从 摄像头 预览 图像中获取yuv(或者格式数据) 转换成 jpeg bmp格式 转成bmp 格式,网上有人说,用 rawByteArray2RGBABitmap2 直接转的效率更高 Camera.P ...

  2. y4m格式和yuv、bmp格式互转

    作为一个从来没做过视频处理的萌新,给我y4m格式的视频真是一脸懵逼 后来尝试了一些笨方法...终于至少能拿出来处理了,记录一下 y4m 格式介绍:https://wiki.multimedia.cx/ ...

  3. 基于Opencv实现连续检测yuv转bmp后的每一帧的sobel算法实现

    算法最重要的一点是要sprintf函数实现动态读取文件名 比如:sprintf(s,"%d", 123); //产生"123" #include <ios ...

  4. FFmpeg Basic学习笔记(4)

    图像处理 常见的图片格式包括YUV.BMP.JPG.GIF.PNG. 图像的创建 可以使用下面命令从输入源中截取图像 ffmpeg -i input -ss t image.type 从videocl ...

  5. 图片格式转换工具与方法

    2019独角兽企业重金招聘Python工程师标准>>> 使用ffmpeg进行格式转换 1.jpg 转 I420 ffmpeg -i 001.jpg -pix_fmt yuv420p ...

  6. [总结]视频质量评价技术零基础学习方法

    前段时间略忙,因此一直计划要总结的很多东西都没来得及写,这两天趁着空闲时间写上一篇.以后等时间充裕了再补充一些内容.本文总结一下学习视频质量评价技术的方法.视频质量评价是我研究生阶段主要的工作,包括发 ...

  7. android图片系统解决方案-从采集到显示

    概述 Android上图片涉及到的要点: 基础 自定义相机拍照 调用系统相机拍照 图片选择 裁剪 压缩 上传 服务端处理与下载 显示与内存-普通图与超大图 文件夹管理 内置图片管理与包大小 基础 颜色 ...

  8. 视频质量评价技术零基础学习方法

    前段时间略忙,因此一直计划要总结的很多东西都没来得及写,这两天趁着空闲时间写上一篇.以后等时间充裕了再补充一些内容.本文总结一下学习视频质量评价技术的方法.视频质量评价是我研究生阶段主要的工作,包括发 ...

  9. 更便捷的中间人攻击框架Xerosploit

    文章首发于FreeBuf 0×00 前言 偶然间,在国外网站的一篇文章中发现有提到这款中间人框架,顺藤摸瓜拿来实践一番,发现确实很可以,确实很方便,不敢独享,特来抛砖引玉,不足之处还望斧正~ 0×01 ...

最新文章

  1. DataRow判断列名是否存在
  2. 高级计算机网络的基本知识
  3. libSVM分类小例C++
  4. koajs 项目实战(二)
  5. 浅谈Spring如何利用三个缓存Map解决循环依赖
  6. LFLT1000 流量计密封性自动化测试系统
  7. 性能分析工具Systrace的使用详解
  8. 英飞凌 AURIX 系列单片机的HSM详解(3)——开发方法
  9. Linux系统管理---RAID磁盘阵列
  10. 14.linux中的无人职守安装脚本kickstart
  11. View和ViewGroup
  12. 梦工厂将在红帽峰会畅谈云计算心得
  13. 交换机常用命令及console口配置
  14. 论文阅读|《用强化学习求解带插单的动态FJSP》
  15. 数据中心运营规划的基本原则
  16. Python自动化测试详解
  17. 小程序源码:修复登录大河盲盒小程序源码,实现运营“玩法自由”,超多功能的盲盒型抽奖挖矿程序源码下载
  18. python画矢量图_使用基于matplotlib的SciencePlots绘制精美图表
  19. 计算机系统时间的修复,电脑时间总是不对,小编教你如何恢复正常
  20. 金庸感人的经典爱情对白

热门文章

  1. 开源数字化校园 CoolSchool即将启动
  2. 计算机没有的文件什么恢复,电脑蓝屏没有保存的文件怎么恢复
  3. ubunto下编译安装opencv方法
  4. 【力扣刷题 | 第十二天】
  5. 有趣的定律4. 彼德原理
  6. 随记——java基础——集合——20200614
  7. 2018.10.26 酷狗音乐校招前端一面经历(转)
  8. xp如何修改时间服务器,WinXP系统解决时间总是不准确操作步骤
  9. matlab图片添加噪音
  10. 小菜鸟的保研经验分享-计算机学科