实验二(1)——8bit像素深度bmp图片与24bit像素深度bmp图片互转2021-03-20

一.实验要求

编写8bit像素深度bmp图片与24bit像素深度bmp图片互相转换的程序,将给定的8bitbmp图片和24bitbmp图片分别转换为24bitbmp图片和8bitbmp图片,其中24bit转换成8bit时,转换规则及8bitbmp图片的调色板自行设定。

二.实验原理

1.8bit转换为24bit

只需将原8bit图像实际位图数据通过查找调色板获得对应的RGB数值直接写入到24bit图像的实际位图数据中。

2.24bit转换成8bit

先自行设定8bit图像的调色板及24bit转8bit的转换规则,将24bit图像的实际位图数据根据转换规则转换为8bit图像的实际位图数据。

三.实验过程

1.变量名称对应图

实验二(1)——8bit像素深度bmp图片与24bit像素深度bmp图片互转2021-03-20_第1张图片

2.8bit转换为24bit:

1)24bit实际位图数据的结构

实验二(1)——8bit像素深度bmp图片与24bit像素深度bmp图片互转2021-03-20_第2张图片

2)完整代码

#include
#include
int main(int argc,char** argv)
{
	char *filename_8,*filename_24;
	filename_8=argv[1];
	filename_24=argv[2];
	BITMAPFILEHEADER eight_bit_f,twenty_4_bit_f;
	BITMAPINFOHEADER eight_bit_info,twenty_4_bit_info;
	RGBQUAD eight_color_buffer[256];
	unsigned char *eight_buffer=NULL,*twenty_4_buffer=NULL;//存放实际位图数据
	unsigned char *twenty_4_buffer_wr;
	unsigned char *eight_buffer_del,*twenty_4_buffer_del;
	FILE *fp_8,*fp_24;
	fp_8=fopen(filename_8,"rb");
	fp_24=fopen(filename_24,"wb");
	fread(&eight_bit_f,sizeof(BITMAPFILEHEADER),1,fp_8);
	fread(&eight_bit_info,sizeof(BITMAPINFOHEADER),1,fp_8);
	fread(&eight_color_buffer,sizeof(RGBQUAD),256,fp_8);
	//*需要判断图像大小是否为四字节整数倍(若不是biSizeImage凑整,并且在二进制文件末尾补零,即在图片第一行前补黑电平行,知道行数为4的整数倍)*/
	int size=eight_bit_info.biSizeImage;
	eight_buffer=new unsigned char[size];
	twenty_4_buffer=new unsigned char[3*size];
	if(eight_buffer==NULL||twenty_4_buffer==NULL)
	{
		printf("can not new unsigned char/n");
	}
	int size_arc=size;//实际图片大小
	//判断宽高是否有一个为四的倍数
	if((eight_bit_info.biHeight%4!=0) && (eight_bit_info.biWidth%4!=0))
	{
		size_arc=eight_bit_info.biHeight*eight_bit_info.biWidth;
	}
	fread(eight_buffer,sizeof(unsigned char),size,fp_8);
	twenty_4_buffer_wr=twenty_4_buffer;
	twenty_4_buffer_del=twenty_4_buffer;
	eight_buffer_del=eight_buffer;
	if(eight_bit_f.bfType!=0x4D42)//判断是否为bmp文件(?直接读出的bfType字节序也是反的吗)
	{
		printf("please input .bmp file/n");
	}
	for(int i=0;i

3)注意事项

用windows.h头文件,可直接使用两个header

3.24bit转换为8bit:

1)8bit图像调色板及转换规则的设计

*调色板设计思路:共RGB三个分量,设每个分量有x种取值,故RGB共x^{3}种取值,令x^{3}<256且x^{3}最接近256,可得x=6。R、G、B分别有六种取值,且R、G、B的取值范围都在0~255,故取每个分量六种取值之间的增量为42(42*6=252,最接近256),即以R为例,若24bit图中R取值为0~41则8bit图中R取21,若24bit图中R取值为42~81则8bit图中R取(42+21),以此类推。

*调色盘0~255的划分:

实验二(1)——8bit像素深度bmp图片与24bit像素深度bmp图片互转2021-03-20_第3张图片

2)关键代码及分析

for(int i=0;i

twenty_4_bit_buffer指向当前像素的B值,twenty_4_bit_buffer+1指向当前像素的G值,twenty_4_bit_buffer+2指向当前像素的R值,将24bit实际位图数据转换为8bit实际位图数据时先判断R值再判断G值最后判断B值,将调色板看作数组,以R为例,若R值在(0,41)之间,则其对应数据一定在调色板256个数组的前36个数组中,即在上图对应的R1区域中,以此类推。

3)完整代码

#include
#include
int main(int argc,char** argv)
{
	char *filename_8,*filename_24;
	filename_8=argv[1];
	filename_24=argv[2];
	BITMAPFILEHEADER eight_bit_f,twenty_4_bit_f;
	BITMAPINFOHEADER eight_bit_info,twenty_4_bit_info;
	RGBQUAD eight_color_buffer[256];
	unsigned char *eight_buffer=NULL,*twenty_4_buffer=NULL;//存放实际位图数据
	unsigned char *eight_buffer_del,*twenty_4_buffer_del;
	unsigned char *eight_buffer_wr;
	FILE *fp_8,*fp_24;
	fp_8=fopen(filename_8,"wb");
	fp_24=fopen(filename_24,"rb");
	fread(&twenty_4_bit_f,sizeof(BITMAPFILEHEADER),1,fp_24);
	fread(&twenty_4_bit_info,sizeof(BITMAPINFOHEADER),1,fp_24);
	//设计8bit调色板
	int color=0;
	for(int r=0;r<6;r++)
	{
		for(int g=0;g<6;g++)
		{
			for(int b=0;b<6;b++)
			{
				eight_color_buffer[color].rgbBlue=b*42+21;
				eight_color_buffer[color].rgbGreen=g*42+21;
				eight_color_buffer[color].rgbRed=r*42+21;
				eight_color_buffer[color].rgbReserved=0;
				color++;
			}
		}
	}
	//218到255之间被浪费
	while(color<256)
	{
		eight_color_buffer[color].rgbBlue=eight_color_buffer[color].rgbGreen=eight_color_buffer[color].rgbRed=eight_color_buffer[color].rgbReserved=0;
		color++;
	}
	int size=twenty_4_bit_info.biSizeImage/3;
	eight_buffer=new unsigned char[size];
	twenty_4_buffer=new unsigned char[3*size];
	eight_buffer_wr=eight_buffer;
	twenty_4_buffer_del=twenty_4_buffer;
	eight_buffer_del=eight_buffer;
	if(eight_buffer==NULL||twenty_4_buffer==NULL)
	{
		printf("can not new unsigned char/n");
	}
	fread(twenty_4_buffer,sizeof(unsigned char),size*3,fp_24);
	int size_arc=size;
	if((twenty_4_bit_info.biHeight%4!=0) && (twenty_4_bit_info.biWidth%4!=0))
	{
		size_arc=twenty_4_bit_info.biHeight*twenty_4_bit_info.biWidth;
	}
	for(int i=0;i

四.实验结果

转换生成的24bit图像与上课发的24bit图像对比(左边是发的,右边是8bit转24bit生成的)

实验二(1)——8bit像素深度bmp图片与24bit像素深度bmp图片互转2021-03-20_第4张图片

转换生成的8bit图像与上课发的8bit图像对比(左边是发的,右边是24bit转8bit生成的)

实验二(1)——8bit像素深度bmp图片与24bit像素深度bmp图片互转2021-03-20_第5张图片

结果分析:转换生成的图片与课上发的图片在色彩上有细微差别,可能是调色板的设计不同造成的。

你可能感兴趣的:(实验二(1)——8bit像素深度bmp图片与24bit像素深度bmp图片互转2021-03-20)