不同像素深度的BMP文件互转

本文详细介绍了BMP文件的格式,包括位图文件头、位图信息头和调色板。阐述了如何实现8位BMP转24位BMP以及24位BMP转8位BMP的算法,探讨了调色板的设计和像素深度转换中的细节问题。通过实验结果展示了转换效果。
摘要由CSDN通过智能技术生成

实验目的

1.理解图像文件的基本组成。
2.掌握结构体作为复杂数据对象的用法。进一步熟悉由问题到程序的解决方案,并掌握
编程细节:如内存分配、倒序读写、字节序、文件读写过程等。

方法解释

文件格式

注释:

1 WORD = 2 BYTE
1 DWORD= 2 WORD = 4 BYTE
1 LONG = 2 DWORD = 8 BYTE

BMP,全称为“bitmap”,中文译为“位图”

BMP文件格式

在这里插入图片描述
补充说明24位BMP文件,每个像素的RGB分量可以直接用24位的三个字节表示,所以没有调色板

位图文件头格式

在这里插入图片描述
补充说明:

bfType 表示位图类别,根据不同的操作系统而不同,在Windows中,此字段的值总为‘BM’(424d)

bfSize 说明的是整个bmp文件的大小,以字节为单位

bfOffBits 说明的是位图文件头+位图信息头+调色板的大小

BMP文件头固定长度为14字节(0x28)

位图文件头格式

在这里插入图片描述
补充说明:

bitCompression 表示压缩方式,0表示不压缩,1表示RLE8压缩,2表示RLE4压缩,3表示每个像素值由指定的掩码决定

BMP信息头固定长度为40字节

调色板

在这里插入图片描述
补充说明:
以8位位图为例,每个像素由一个8bit字节存储,一个8bit字节能表示256个数(索引值 或 数组下标),所以文件信息头之后,图像数据之前,需要存放256*4字节长度的调色板,依次按照颜色对应的索引值顺序,4字节4字节存放,每四个字节按照B、G、R、保留值(为0)顺序存储。显示图片时,按照图像数据所存储的索引值,在调色板中查找对应的BGR分量,还原该像素颜色。

图像数据

在这里插入图片描述
比如,一字节可以表示8个1位彩色深度像素,2个4位,或1个8位
在这里插入图片描述
若不是4的整数倍,需要合理补齐,比如末位补0等,否则无法正常读取文件
在这里插入图片描述

24位BMP文件格式

24位BMP文件没有调色板,数据图像用3个字节表示一个像素

8位BMP文件格式

8位BMP文件,在信息头后面存放了256*4长度的调色板,数据图像用1个字节表示一个像素

算法说明

8位BMP转24位BMP

创建pRGB结构体数组读取8位BMP调色板信息

bool MakePalette(FILE* pFile, BITMAPFILEHEADER& file_h, BITMAPINFOHEADER& info_h, RGBQUAD* pRGB_out)
{
   
	if ((file_h.bfOffBits - sizeof(BITMAPFILEHEADER) - info_h.biSize) == sizeof(RGBQUAD) * pow(2, (double)info_h.biBitCount))
	{
   
		fseek(pFile, sizeof(BITMAPFILEHEADER) + info_h.biSize, 0);
		fread(pRGB_out, sizeof(RGBQUAD), (unsigned int)pow(2, (double)info_h.biBitCount), pFile);
		return true;
	}
	else
		return false;

}

每读取一个字节,根据该字节去查找调色板,转换成BGR,直到fread读到文件末,返还0结束循环

while(fread(clrIndex, sizeof(uint8_t), 1, bmpFile))
		{
   
			*clr = pRGB[*clrIndex].rgbBlue;
			clr++;
			*clr = pRGB[*clrIndex].rgbGreen;
			clr++;
			*clr = pRGB[*clrIndex].rgbRed;
			clr++;
		}

改文件头和信息头
图像数据的大小 改为 24bit图像数据大小
偏移量删除调色板长度 改为 文件头+信息头
重置文件大小
像素深度 从8改为24

	info_h.biSizeImage = info_h.biSizeImage * 3;

	file_h.bfOffBits = 14 + info_h.biSize;
	file_h.bfSize = file_h.bfOffBits + info_h.biSizeImage;

	info_h.biBitCount = 24;

24位BMP转8位BMP

调色板设计

8bit彩色深度可以表示256种颜色,若想rgb三种像素值在(0~255)的颜色组合表示256中颜色,假设每种颜色有相同种类的像素值,那么63=216<256<343=73,若每种颜色有6种像素值等级,那么会有许多像素值不好分配。

所以想能否改变其中一种颜色像素值等级数,若其中一个改成7,那么能组合出来的颜色组合有6x6x7=252种,非常接近255种。人眼对绿色的敏感度在色谱中会较高,所以这里采取把绿色分成7个等级的方式,去设计调色板。

将256个像素平分成6个等级,则每个等级代表的的区间长度为256/6=42,采取用中间值代表整个区间的方式,以42/2=21作为第一等级像素值代表[0,41]区间的像素值,后四个等级区间依次递增42。绿色则同理,每个等级区间长度为256/7=36,以18为代表第一像素等级区间[0,35]的值,后六个等级依次递增36,最后剩下的256-252=4种颜色,让rgb同时递增小值,接近最高值255

int index = 0;

	int r;
	int g;
	int b;

	for (r = 0; r < 6; r++) {
   
		for (g = 0; g < 7; g++) {
   
			for (b = 0; b < 6; b++) {
   
				Palette[index].rgbRed = 21 + 42 * r;
				Palette[index].rgbBlue = 21 + 42 * b;
				Palette[index].rgbGreen = 18 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值