音视频编解码–BMP格式

BMP图像是一种光栅图像(包含像素数据而不是矢量图像)格式。BMP图像的每个像素由单个位或一组位定义。自个人计算早期就已存在。它是一种无损格式,意味着保存图像时不会丢失任何信息。但是,它也是一种非常大的格式,因此难以存储和传输。

BMP 发展历程

根据 Microsoft 的支持文档描述:

设备无关位图(DIB)是一种格式,用于在各种颜色分辨率下定义设备无关位图。DIBs 的主要目的是允许位图从一个设备移动到另一个设备(因此,“设备无关”是名称的一部分)。与设备相关位图在系统中作为位图对象出现不同,DIB是一种外部格式。通常使用元文件(通常使用 StretchDIBits() 函数)、BMP 文件和剪贴板(CF_DIB 数据格式)传输 DIB。所以bmp文件又称为DIB文件。

图像对比

图片

BMP 文件结构

依据资料进行文件结构整理,大概内容如下表所示:

图片

后来在Wiki百科中有一张图比较经典,非常清晰明了的说明了BMP的图像格式结构特点,特地引用该图作为文件结构的整体理解框图

https://en.wikipedia.org/wiki/BMP_file_format#/media/File:BMPfileFormat.svg

图片

BMP 特点

BMP文件格式支持以下压缩方法:

无压缩(Uncompressed):每个像素都由一个固定数量的位数表示,在图像数据中依次存储。

RLE8 压缩(RLE8 Compression):使用行程长度编码(Run-length encoding)压缩算法,对每个像素进行编码,并将其与图像数据一起存储。这种压缩算法适用于颜色深度为8位的位图。

RLE4 压缩(RLE4 Compression):与 RLE8 压缩类似,但是每个像素只有4位,因此需要更高效的压缩算法。这种压缩算法适用于颜色深度为4位的位图。

PS:需要注意的是,虽然 BMP 文件格式支持上述两种压缩算法,但是它们并不常用,因为它们在很多情况下无法有效地减小文件大小。通常情况下,BMP 格式不进行压缩,而是直接存储原始的像素数据。

OS/2 BITMAPCOREHEADER2 24bpp 图像可以使用 24 位 RLE 算法进行压缩。

OS/2 是 IBM 公司开发的操作系统,BITMAPCOREHEADER2 是 OS/2 中用于存储位图图片信息的结构体,其中包含了位图的基本信息,如宽度、高度、颜色深度等。而 24bpp 则表示该位图的颜色深度为 24 位每像素。

BMP 透明特性

BMP文件格式有两种类型的 Alpha 值,即透明度值和位域遮罩。这些值通常在位图文件头中定义,并用于指定每个像素的透明度。

第一种类型,透明度值 Alpha 值被称为透明度分量(Alpha Channel),它是一个8位无符号整数,在每个像素中添加一个单独的通道来表示像素的透明度。这种透明度分量被称为Alpha 位图或 RGBA 位图,其中 A 表示 Alpha 值。

另一种类型,Alpha 值是位域遮罩,它是一个32位无符号整数,指定哪些位用于表示颜色值,哪些位用于表示透明度值。这种 Alpha 值通常称为 Alpha 位域。通过使用 Alpha 位域,可以更精细地控制像素的不透明度,同时保留完整的颜色信息。

代码走读

依然是参考FFMPEG中代码,其主要文件如下:

libavcodecbmp.c

libavcodecbmp.h

libavcodecbmpenc.c

libavcodecbmpenc.h

FFMPEG中规范定义相关的结构体:

图片

bmp_encode_init

该函数是BMP图像编解码器上下文初始化过程的一部分。根据输入视频帧的像素格式(pix_fmt)设置AVCodecContext的bits_per_coded_sample字段。对于每种受支持的像素格式,它设置适当的每个样本位数。

图片

bmp_encode_frame

这是一个名为bmp_encode_frame的函数,它使用给定的AVCodecContext和AVFrame进行BMP图像编码,并将结果存储在AVPacket中。如果成功编码,则got_packet参数将被设置为1。该函数首先根据像素格式(pix_fmt)设置压缩类型、调色板和每个样本位数等变量,并计算图像数据大小并分配足够的内存

图片

填充BITMAPFILEHEADER和BITMAPINFOHEADER结构体

图片

将调色板写入pkt->data中,并将像素数据从给定的AVFrame复制到AVPacket的data中,实现了BMP图像的编码。

需要注意的是,由于BMP文件是从底部向上存储像素数据的,因此在写入像素数据时需要从图像的末尾开始,并在每行结束时添加适当数量的填充字节以使每行字节数为4的倍数。

图片

至此FFMPEG中bmpenc的文档就解析完成,相比之前的部分要简单一些。

BMP Decoder

bmp.c文件中是解码相关代码逻辑,这个文件也仅仅一个解码API,所以我们顺手一起了解一下:

图片

bmp_decode_frame

首先也是先做一下初始化操作,同时检验解码图像是否是BMP文件格式:

图片

以上是本文的所有内容,希望对有需要的小伙伴有所帮助。

作者简介:一枚爱跑步的程序猿,维护公众号和知乎专栏《MediaStack》,有兴趣可以关注,一起学习音视频知识,时不时分享实战经验。

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论