当biBitCount=1、4、8(且biClrUsed==0)时,N=2,16,256若biClrUsed!=O,则N=biClrUsed。在BMP文件中,即使是单色的BMP图像文件,也必须存放调色板数据,第一组的三原色代表背景颜色,第二组的三原色则代表前景颜色。(2)BMP数据压缩方法BMP图像文件对图像数据有三种处理方式:(a)不压缩数据,任何BMP图像文件都是以这种方式处理。(b)RLE4压缩法,这是专用于16色图像数据的压缩方法。(c)RLE8压缩法,这是专用于256色图像数据的压缩方法。目前有些软件只能存取不压缩的BMP图像文件数据,而无法处理经过压缩处理的BMP图像文件。(a)不压缩的图像数据这是BMP图像文件通用的数据处理方式,虽然这种作法会使得BMP图像文件的大小大于其它有压缩处理的图像文件。不过,少了一道压缩或解解压缩的手续,也让BMP图像文件的读文件或存文件速度超过其它经过压缩处理的图像文件,既然没有了压缩处理的问题,只要了解图像数据的排列及存储方式,就能正确的处理未压缩数据的BMP图像文件。BMP图像文件内的图像数据排列顺序与众不同。它是以图像的左下角为起点,按照由左至右,由上而下的次序,将图像数据一点一点存入文件。这与其它图像文件的数据存放顺序稍有不同,其它图像文件都是以图像的左上角作为起点。图像数据的存储方式:单色图像是以一个字节记录八点,16色图像是以一个字节记录两点,左边四个Bits存第一点,右边四个Bits存第二点,256色图像是以一个字节记录一点。至于全彩色图像则是三个字节记录一点,而以RGB,RGB,RGB...的次序排列下来。除此之外,BMP图像文件有一个很特殊的规定:文件内每行字节的个数,必须是4的倍数。若未达到4的倍数,必须在每行的末端加上几个字节,以补足差额。因此,在读取没有压缩处理的BMP图像文件时,要注意每行是否包含多余的字节,避免将多余的字节存入主存储单元内,进而造成显示图像时,屏幕上出现一些错误的的图像内容。(b)RLE4压缩法RLE4压缩法同样有着一般RLE压缩理论的特色:以两个字节代表一串相同数值的图像数据。不过,RLE4压缩法还具有两个与众不同的设计:计数方式和识别码。计数方式在一般RLE压缩理论中,以两个字节代表一串相同数值的数据,第一个字节表示有多少个相同的字节,第二字节则代表此相同的数值,例如,0x06,0x29即表示有连续6个字节的0x29。但是,在RLE4压缩法中,0x06,0x29却是代表有3个连续的0x29。压缩码的第一4
4 当 biBitCount=1、4、8(且 biClrUsed==0)时,N=2,16,256; 若 biClrUsed!=0,则 N=biClrUsed。 在 BMP 文件中,即使是单色的 BMP 图像文件,也必须存放调色板数据,第一组的三 原色代表背景颜色,第二组的三原色则代表前景颜色。 (2)BMP 数据压缩方法 BMP 图像文件对图像数据有三种处理方式: (a)不压缩数据,任何 BMP 图像文件都是以这种方式处理。 (b)RLE4 压缩法,这是专用于 16 色图像数据的压缩方法。 (c)RLE8 压缩法,这是专用于 256 色图像数据的压缩方法。 目前有些软件只能存取不压缩的 BMP 图像文件数据,而无法处理经过压缩处理的 BMP 图像文件。 (a)不压缩的图像数据 这是 BMP 图像文件通用的数据处理方式,虽然这种作法会使得 BMP 图像文件的大小 大于其它有压缩处理的图像文件。不过,少了一道压缩或解解压缩的手续,也让 BMP 图 像文件的读文件或存文件速度超过其它经过压缩处理的图像文件,既然没有了压缩处理的 问题,只要了解图像数据的排列及存储方式,就能正确的处理未压缩数据的 BMP 图像文 件。 BMP 图像文件内的图像数据排列顺序与众不同。它是以图像的左下角为起点,按照 由左至右,由上而下的次序,将图像数据一点一点存入文件。这与其它图像文件的数据存 放顺序稍有不同,其它图像文件都是以图像的左上角作为起点。 图像数据的存储方式:单色图像是以一个字节记录八点,16 色图像是以一个字节记录 两点,左边四个 Bits 存第一点,右边四个 Bits 存第二点,256 色图像是以一个字节记录一 点。 至于全彩色图像则是三个字节记录一点,而以 RGB,RGB,RGB的次序排列下来。 除此之外,BMP 图像文件有一个很特殊的规定:文件内每行字节的个数,必须是 4 的倍数。若未达到 4 的倍数,必须在每行的末端加上几个字节,以补足差额。因此,在读 取没有压缩处理的 BMP 图像文件时,要注意每行是否包含多余的字节,避免将多余的字 节存入主存储单元内,进而造成显示图像时,屏幕上出现一些错误的的图像内容。 (b)RLE4 压缩法 RLE4 压缩法同样有着一般 RLE 压缩理论的特色:以两个字节代表一串相同数值的图 像数据。不过,RLE4 压缩法还具有两个与众不同的设计:计数方式和识别码。 计数方式 在一般 RLE 压缩理论中,以两个字节代表一串相同数值的数据,第一个字节表示有 多少个相同的字节,第二字节则代表此相同的数值,例如,0x06,0x29 即表示有连续 6 个 字节的 0x29。 但是,在 RLE4 压缩法中,0x06,0x29 却是代表有 3 个连续的 0x29。压缩码的第一
个字节值为0x06,是表示6点图像数据,而非6个字节。这种特殊的计数方式,可以说是为了配合BMP图像文件16色图像数据的存储法。BMP图像文件是以1个字节存储两点的方式,来存放16色图像数据。识别码识别码一共有四种,每种识别码的第一个字节必定是0。以下说明四种识别码的定义。(1)0x000x00表示一行图像数据的结束。RLE4压缩法将一行视为一个压缩单元,每行经过压缩后,都会在压缩数据的末端加入0x000x00两个字节。(2)0x000x01表示所有图像数据的结束。当所有的行都压缩存档之后,就加入0x00:0x01两个字节,作为结束的标志。(3)0x000x01XY表示向右移X点,向下移Y点。这是当背景画面确立之后,想在背景的某个区域加入图像时,就先在这一小块图像数据的前面,加上这段控制码。(4)0x00N...表示有N点不同值的图像数据。如果不同值的图像数据为奇数个字节,必须在数据的末端加入0x00,以维持压缩数据长度为偶数个字节。BMP图像文件规定压缩数据的字节数必须是偶数。例如:原始数据0x570x380x260x370x750x360x360x360x36...压缩数据0x000x0a0x570x380x260x370x750x000x080x36...0x570x380x260x370x75一共是5个字节,压缩数据需要加入一个0x00,以便将数据长度凑成偶数。总上所述,用以下的例子解释RLE4压缩法,假如有两列图像数据等待压缩。原始数据第一列0x360x360x510x270x360x320x830x27...0x270x270x270x27第二列0x960x980x420x170x770x770x770x77...0x620x620x620x62压缩数据第一列0x060x3650x320x830x510x000x0400x000x060x27...0x060x000x270x00第二列0x000x080x960x980x420x170x080x77...0x040x620x020x000x000x010x810x00从上述原始数据和压缩数据的对照之下,应当可以体会RLE4压缩法的编码规则。(c)RLE8压缩法RLE8压缩法与RLE4压缩法非常类似,所以只是计数方式有所不同。在RLE8压缩法中,压缩码的第一个字节代表有几个字节的数据值相同。因为RLE8压缩法只用于压缩256色图像数据,而256色图像数据正好是一个字节存储一点,所以计数方式便与RLE4压缩法不同。只要观察下列例子,看这两种压缩方式如何压缩处理同一串数据,即可分辨出两种方法的差异。原始数据0x820x820x820x820x960x460x335
5 个字节值为 0x06,是表示 6 点图像数据,而非 6 个字节。这种特殊的计数方式,可以说是 为了配合 BMP 图像文件 16 色图像数据的存储法。BMP 图像文件是以 1 个字节存储两点 的方式,来存放 16 色图像数据。 识别码 识别码一共有四种,每种识别码的第一个字节必定是 0。以下说明四种识别码的定义。 (1)0x00 0x00 表示一行图像数据的结束。RLE4 压缩法将一行视为一个压缩单 元,每行经过压缩后,都会在压缩数据的末端加入 0x00 0x00 两个字节。 (2)0x00 0x01 表示所有图像数据的结束。当所有的行都压缩存档之后,就加 入 0x00 0x01 两个字节,作为结束的标志。 (3)0x00 0x01 X Y 表示向右移 X 点,向下移 Y 点。这是当背景画面确立 之后,想在背景的某个区域加入图像时,就先在这一小块图像数据的前面,加上这段控制 码。 (4)0x00 N 表示有 N 点不同值的图像数据。如果不同值的图像数据为奇数 个字节,必须在数据的末端加入 0x00,以维持压缩数据长度为偶数个字节。BMP 图像文 件规定压缩数据的字节数必须是偶数。例如: 原始数据 0x57 0x38 0x26 0x37 0x75 0x36 0x36 0x36 0x36 压缩数据 0x00 0x0a 0x57 0x38 0x26 0x37 0x75 0x00 0x08 0x36 0x57 0x38 0x26 0x37 0x75 一共是 5 个字节,压缩数据需要加入一个 0x00,以 便将数据长度凑成偶数。 总上所述,用以下的例子解释 RLE4 压缩法,假如有两列图像数据等待压缩。 原始数据 第一列 0x36 0x36 0x36 0x32 0x83 0x51 0x27 0x270x27 0x27 0x27 0x27 第二列 0x96 0x98 0x42 0x17 0x77 0x77 0x77 0x770x62 0x62 0x62 0x62 压缩数据 第一列 0x06 0x36 0x00 0x06 0x32 0x83 0x51 0x00 0x04 0x270x06 0x27 0x00 0x00 第二列 0x00 0x08 0x96 0x98 0x42 0x17 0x08 0x770x04 0x62 0x02 0x81 0x00 0x00 0x00 0x01 从上述原始数据和压缩数据的对照之下,应当可以体会 RLE4 压缩法的编码规则。 (c)RLE8 压缩法 RLE8 压缩法与 RLE4 压缩法非常类似,所以只是计数方式有所不同。在 RLE8 压缩 法中,压缩码的第一个字节代表有几个字节的数据值相同。因为 RLE8 压缩法只用于压缩 256 色图像数据,而 256 色图像数据正好是一个字节存储一点,所以计数方式便与 RLE4 压缩法不同。只要观察下列例子,看这两种压缩方式如何压缩处理同一串数据,即可分辨 出两种方法的差异。 原始数据 0x82 0x82 0x82 0x82 0x96 0x46 0x33
0x0830x8220x000x060x960x460x330x00RLE4压缩数据RLE8压缩数据0x0440x8220x000x030x960x460x330x00除计数方式的差异之外,本压缩方法与RLE4压缩法完全相同,不再加以说明。2.图像的直方图图像的(灰度统计)直方图是一个一维的离散函数。它的定义为:设Sk为图像f(x,y)的第k级灰度值,nk是f(x,y)中具有灰度值Sk的象素的个数,n是图像象素总数,则:ps(sk)=n/nk=0,1,...,L-1称为图像f(x,y)的直方图。这里ps(sk)代表原始图中第k个灰度级的出现概率。以n为自变量,以p(sk)为函数,得到的曲线就是图像的直方图,在实际中常常直接将对第k个灰度级的统计值n作为图像的直方图。它提供了原图灰度值的分布情况,也可以说给出了一幅图所有灰度值的整体描述。对灰度图像进行直方图统计的程序流程图如图2-2所示。输输出按照图像中灰度入如果f(xy)-i,直的级数建立数组图则,G(i)=G(i)+1方G(i)像图图2-2灰度图像直方图统计流程三、实验前准备1.预习本实验中关于BMP图像文件的基本格式;2.了解本实验的目的和实验内容。四、实验内容1.根据BMP图像文件的基本格式,利用C编写8bits无压缩BMP图像文件的打开和存储的程序;2.用所编程序对给定图像进行读写操作3.编写对灰度图像进行直方图统计的程序,并将结果显示在屏幕上。五、实验报告要求1.总结对8bits无压缩BMP图像文件的读写操作过程:2.总结对灰度图像进行直方图统计的过程,比较不同的图像其直方图特性:3.对实验结果进行分析。六、参考程序6
6 RLE4 压缩数据 0x08 0x82 0x00 0x06 0x96 0x46 0x33 0x00 RLE8 压缩数据 0x04 0x82 0x00 0x03 0x96 0x46 0x33 0x00 除计数方式的差异之外,本压缩方法与 RLE4 压缩法完全相同,不再加以说明。 2.图像的直方图 图像的(灰度统计)直方图是一个一维的离散函数。它的定义为: 设 sk 为图像 f(x,y)的第 k 级灰度值,nk 是 f(x,y)中具有灰度值 sk的象素的个数,n 是图像象素总数,则: ps(sk)= nk/n k=0,1,,L-1 称为图像 f(x,y)的直方图。 这里 ps(sk)代表原始图中第 k 个灰度级的出现概率。以 nk为自变量,以 ps(sk)为函数, 得到的曲线就是图像的直方图,在实际中常常直接将对第 k 个灰度级的统计值 nk 作为图像 的直方图。 它提供了原图灰度值的分布情况,也可以说给出了一幅图所有灰度值的整体描述。 对灰度图像进行直方图统计的程序流程图如图 2-2 所示。 图 2-2 灰度图像直方图统计流程 三、实验前准备 1.预习本实验中关于 BMP 图像文件的基本格式; 2.了解本实验的目的和实验内容。 四、实验内容 1.根据 BMP 图像文件的基本格式,利用 C 编写 8bits 无压缩 BMP 图像文件的打开和存储 的程序; 2.用所编程序对给定图像进行读写操作 3.编写对灰度图像进行直方图统计的程序,并将结果显示在屏幕上。 五、实验报告要求 1.总结对 8bits 无压缩 BMP 图像文件的读写操作过程; 2.总结对灰度图像进行直方图统计的过程,比较不同的图像其直方图特性; 3.对实验结果进行分析。 六、参考程序 输 入 图 像 按照图像中灰度 的级数建立数组 G(i) 如 果 f(x,y)=i , 则,G(i)=G(i)+1 输 出 直 方 图
BMP图像文件读写及直方图统计程序流程图用fopenO打开BMP图像文件用freadO读取表头数据检查文件格式错误退出正确用fopenO打开待写文件用fwriteO写入表头数据读取/写入调色板计算图像的行宽nn=[(biWidth+3)/4]*4读取/写图像数据for(i=0.i<d:i++)for(i=0:j<nn;i++)fread(&color,1,1,fp),fwrite(&color,1,1,FL2), )对图像进行直方图统计用fclose(关闭图像文件在屏幕上显示直方图数据7
7 BMP 图像文件读写及直方图统计程序流程图 错误 用 fopen()打开 BMP 图像文件 用 fread()读取表头数据 检查文件格式 退出 用 fopen()打开待写文件 用 fwrite()写入表头数据 读取/写入调色板 计算图像的行宽 nn= [(biWidth+3)/4]*4 读取/写图像数据 for(i=0;i<d;i++) for(j=0;j<nn;j++) { fread(&color,1,1,fp); fwrite(&color,1,1,FL2); } 对图像进行直方图统计 用 fclose()关闭图像文件 在屏幕上显示直方图数据 正确
BMP图像文件读写及直方图统计参考程序/*参数值Width影像宽度影像高度HeigheColor图像数据本程序输入、输出都为无压缩8BitBMP文件,对图像文件的大小不限使用方法:执行文件名输入文件名.bmp车输出文件名.bmp其中输入文件和输出文件都放在与执行文件相同的目录下*#include<stdio.h>#include<conio.h>#include<stdlib.h>typedef structchar bfType[2];long bfSize;intbfReservedl;intbfReserved2:long bfoffBits;BITMAPFILEHEADER:typedef structlongbiSize;long biWidth;long biHighth,int biPlanes;int biBitCount;longbiCompress,long biSizelmage;longbiXpelsPerMeter,long biYpelsPerMeter,long biClrUsed;long biClrlmportant;!BITMAPINFOHEADERtypedef structtagRGBQUADunsigned char rgbBlue8
8 BMP 图像文件读写及直方图统计参考程序 /*参数值 Width 影像宽度 Heighe 影像高度 Color 图像数据 本程序输入、输出都为无压缩 8Bit BMP 文件,对图像文件的大小不限 使用方法: 执行文件名 输入文件名.bmp 输出文件名.bmp 其中输入文件和输出文件都放在与执行文件相同的目录下*/ #include <stdio.h> #include <conio.h> #include <stdlib.h> typedef struct { char bfType[2]; long bfSize; int bfReserved1; int bfReserved2; long bfoffBits; }BITMAPFILEHEADER; typedef struct { long biSize; long biWidth; long biHighth; int biPlanes; int biBitCount; long biCompress; long biSizeImage; long biXpelsPerMeter; long biYpelsPerMeter; long biClrUsed; long biClrImportant; }BITMAPINFOHEADER; typedef struct tagRGBQUAD { unsigned char rgbBlue;