读取并修改bmp文件

要求

对bmp格式的图片进行读取和修改,修改某些信息后储存。

使用工具

CodeBlocks、C++语言、bmp格式的图片一张。

具体内容

准备bmp图片

由于现在的图片大多采用jpg格式存储,bmp格式的图片并不常见,所以要先获得bmp格式的图片一张。可以将其他格式的图片转化成bmp格式。用windows的画图工具打开并以.bmp格式另存为即可。

1571663695302

BMP的存储格式

BMP文件的数据按照从文件头开始的先后顺序分为四个部分:

  • bmp文件头(bmp file header):提供文件的格式、大小等信息。

  • 位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息。

  • 调色板(color palette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表。

  • 位图数据(bitmap data):图像数据。

具体内容教材中都给出,这里不再做详细解释。

二进制形式读取BMP图像

信息以二进制形式存储,自然可以用二进制的方式读取。又很多工具可以以二进制形式读取文件,如notpad++等,这里我使用的是Sublime,要先安装 HexViewer 插件,具体安装步骤和使用方式百度查得。

1571660881601

可以看到BM标识、文件头、信息头等信息都可以正确读取。

使用C++读取BMP图片

要掌握c++的fread函数,先读取到文件头和信息头。

利用信息头中的 biBitCount 判断是否有调色板,如有计算出调色板的大小并读入。要注意的一点是调色板中的每个元素对应到结构体中的RGB的顺序是相反的,所以在结构体中定义的顺序是 BGR 。

接下来就是读取图片信息,每次读取一行的像素信息。首先要确定的是图像的长宽,结合 biBitCount 得出每一行像素占用的空间。如果BMP图像在存储过程中会自动对其,若宽度不足4的倍数补全到4的整数倍,所以在计算时要考虑到这一方面。

接下来直接按照高度依次读取每行即可。

使用c++存储BMP图片

存储和读取时类似的,文件头等信息都获得后按读取到的数据写入到文件即可,同样注意的也是要处理每一行像素的自动补全情况。

在写入前可以对图片信息进行修改,我这里是把 RGB 三个值都等于其中最大的一个,即变成灰色,整个图像也都变为了灰色。修改后的图片如下:

1571662568526

总结和感悟

本次实践实现了对BMP图片的读取、修改和存储,其实学会了BMP图片的操作方式,其他类型的图片读取方法也类似,只不过文件头等信息不同,在代码中的处理略有差别,不过整体步骤是类似的。

得到图片的位图数据后可以对其进行各种操作,此处只是将彩色图片转化为黑白图片。在更深入的学习之后可以对数据进行傅里叶变换、几何变换、降噪等各种操作。

通过本次实验,遇到的许多问题,学习到了许多新知识,但也仅仅是掌握了对图像的基本读取,通过更深入的学习,可以对图像进行更多、更复杂的变换,前路漫漫、道阻且长啊!!!

# 使用单$作为行内数学公式分界符