⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitmap2sd256.c

📁 将256色bmp图片转换为yuv格式输出,编译器为g
💻 C
字号:
#include "stdio.h"
#include "stdlib.h"

////BMP文件组成 
////BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 
//
////BMP文件头 
////BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。 
////其结构定义如下: 
//typedef struct tagBITMAPFILEHEADER 
//{ 
//unsigned short int	bfType; 	// 位图文件的类型,必须为BM 
//unsigned long 	bfSize; 	// 位图文件的大小,以字节为单位 
//unsigned short int	bfReserved1; 	// 位图文件保留字,必须为0 
//unsigned short int	bfReserved2; 	// 位图文件保留字,必须为0 
//unsigned long 	bfOffBits; 	// 位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位 
//} BITMAPFILEHEADER; 
//
////BMP位图信息头数据用于说明位图的尺寸等信息。 
//typedef struct tagBITMAPINFOHEADER
//{ 
//unsigned long	biSize; 		// 本结构所占用字节数 
//long	biWidth; 			// 位图的宽度,以像素为单位 
//long	biHeight; 			// 位图的高度,以像素为单位 
//unsigned short int biPlanes; 		// 目标设备的级别,必须为1 
//unsigned short int biBitCount;	// 每个像素所需的位数,必须是1(双色), 4(16色),8(256色)或24(真彩色)之一 
//unsigned long biCompression; 		// 位图压缩类型,必须是 0(不压缩), 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 
//unsigned long biSizeImage; 		// 位图的大小,以字节为单位 
//long	biXPelsPerMeter; 		// 位图水平分辨率,每米像素数 
//long	biYPelsPerMeter; 		// 位图垂直分辨率,每米像素数 
//unsigned long biClrUsed;		// 位图实际使用的颜色表中的颜色数 
//unsigned long biClrImportant;		// 位图显示过程中重要的颜色数 
//} BITMAPINFOHEADER;
//
//
////  颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结 
////构,定义一种颜色。RGBQUAD结构的定义如下: 
//typedef struct tagRGBQUAD 
//{ 
//unsigned char	rgbBlue;		// 蓝色的亮度(值范围为0-255) 
//unsigned char	rgbGreen; 		// 绿色的亮度(值范围为0-255) 
//unsigned char	rgbRed; 		// 红色的亮度(值范围为0-255) 
//unsigned char	rgbReserved;		// 保留,必须为0 
//} RGBQUAD; 
//
////颜色表中RGBQUAD结构数据的个数有biBitCount来确定: 
////当biBitCount=1,4,8时,分别有2,16,256个表项; 
////当biBitCount=24时,没有颜色表项。 
////位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: 
//typedef struct tagBITMAPINFO { 
//BITMAPINFOHEADER bmiHeader; 		// 位图信息头 
//RGBQUAD bmiColors[1]; 		// 颜色表 
//} BITMAPINFO; 
//
////5. 位图数据 
////  位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间 是从下到上。
////位图的一个像素值所占的字节数: 
////当biBitCount=1时,8个像素占1个字节; 
////当biBitCount=4时,2个像素占1个字节; 
////当biBitCount=8时,1个像素占1个字节; 
////当biBitCount=24时,1个像素占3个字节; 
////Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充, 
////一个扫描行所占的字节数计算方法: 
////DataSizePerLine= (biWidth* biBitCount+31)/8; 
////// 一个扫描行所占的字节数 
////DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数 
////位图数据的大小(不压缩情况下): 
////DataSize= DataSizePerLine* biHeight; 
//

unsigned char *sd256_bitmap = NULL;    //包含前8个字节
unsigned char *sd256_YUV = NULL;	//不包含前8个字节,只有调色板和数值索引信息
typedef struct tagBITMAPFILEHEADER 
{ 
unsigned short int	bfType; 	
unsigned long 		bfSize; 	
unsigned short int	bfReserved1; 	
unsigned short int	bfReserved2; 	
unsigned long 		bfOffBits; 	
} BITMAPFILEHEADER; 

typedef struct tagBITMAPINFOHEADER
{ 
unsigned long		biSize; 	
long			biWidth; 		
long			biHeight; 		
unsigned short int 	biPlanes; 	
unsigned short int 	biBitCount;	
unsigned long 		biCompression; 	
unsigned long 		biSizeImage; 	
long			biXPelsPerMeter; 	
long			biYPelsPerMeter; 	
unsigned long 		biClrUsed;	
unsigned long 		biClrImportant;	
} BITMAPINFOHEADER;


typedef struct tagRGBQUAD 
{ 
unsigned char		rgbBlue;		
unsigned char		rgbGreen; 		
unsigned char		rgbRed; 		
unsigned char		rgbReserved;		
} RGBQUAD; 

typedef struct tagBITMAPINFO { 
BITMAPINFOHEADER bmiHeader; 	
RGBQUAD bmiColors[1]; 		
} BITMAPINFO; 

/////////////////////////////////////////////////////////////////
// rgb to yuv conversion routines
// rgb 2 yuv:
// Y  =  0.257r + 0.504g + 0.098b + 16
// Cb = -0.148r - 0.291g + 0.439b + 128
// Cr =  0.439r + 0.368g + 0.071b + 128
static char rgb2y (char r, char g, char b)
{
	long f = 257*(long)r + 504*(long)g + 98*(long)b + 16000;
	if (f > 255000)
		f = 255000;
	f = f / 1000;
	return (char)f;
}
static char rgb2u (char r, char g, char b)
{
	long f = -148*(long)r - 291*(long)g + 439*(long)b + 128000;
	if (f > 255000)
		f = 255000;
	if (f < 0)
		f = 0;
	f = f / 1000;
	return (char)f;
}
static char rgb2v (char r, char g, char b)
{
	long f = 439*(long)r - 368*(long)g - 71*(long)b + 128000;
	if (f > 255000)
		f = 255000;
	if (f < 0)
		f = 0;
	f = f / 1000;
	return (char)f;
}
// end rgb to yuv conversion routines
/////////////////////////////////////////////////////////////////

int ConvertBmpFile (char *BmpFileName, char *HeaderFileName)
{   
	FILE              	*f;
	FILE 			*fp;                     
	BITMAPFILEHEADER	bf;
	BITMAPINFOHEADER	bi;
	unsigned long 		LineBytes;
	unsigned long 		ImgSize;
	unsigned long           i, j, k;
	unsigned long		NumColors;
	unsigned long		sd256_bitmap_len;
	short  int              n, buf[20];
	char  			temp[8];
	char yvalue;
	char uvalue;
	char vvalue;

	f = fopen (BmpFileName,"rb");
	if (f == NULL)
	{
		printf ("can not open bmp file");
		return 0;
	}

	memset (buf, 0, sizeof (buf));
	n = fread (buf, 2, 7, f);
	printf ("n = %d\n", n);

	bf.bfType      = buf[0];
	bf.bfSize      = (unsigned long) buf[1]; 
	bf.bfReserved1 = buf[3];
	bf.bfReserved2 = buf[4];
	bf.bfOffBits   = (unsigned long) buf[5]; 
	printf ("bf.bfType        = %d\n", bf.bfType);
	printf ("bf.bfSize        = %d\n", bf.bfSize);
	printf ("bf.bfReserved1   = %d\n", bf.bfReserved1);
	printf ("bf.bfReserved2   = %d\n", bf.bfReserved2);
	printf ("bf.bfOffBits     = %d\n", bf.bfOffBits);

	fseek (f, 14, SEEK_SET);
	memset (buf, 0, sizeof (buf));

	n = fread (buf, 2, 40, f);
	printf ("n = %d\n", n);

	bi.biSize          	= (unsigned long) buf[0];
	bi.biWidth         	= (long) buf[2];
	bi.biHeight        	= (long) buf[4];
	bi.biPlanes      	= buf[6];
	bi.biBitCount    	= buf[7];
	bi.biCompression	= (unsigned long) buf[8];
	bi.biSizeImage  	= (unsigned long) buf[10];
	bi.biXPelsPerMeter	= (long) buf[12];
	bi.biYPelsPerMeter	= (long) buf[14];
	bi.biClrUsed   		= (unsigned long) buf[16];
	bi.biClrImportant	= (unsigned long) buf[18];
	
	printf ("bi.biSize          	 = %d\n", bi.biSize);
	printf ("bi.biWidth         	 = %d\n", bi.biWidth);
	printf ("bi.biHeight        	 = %d\n", bi.biHeight);
	printf ("bi.biPlanes      	 = %d\n",  bi.biPlanes);
	printf ("bi.biBitCount    	 = %d\n",  bi.biBitCount);
	printf ("bi.biCompression	 = %d\n", bi.biCompression);
	printf ("bi.biSizeImage  	 = %d\n", bi.biSizeImage);
	printf ("bi.biXPelsPerMeter	 = %d\n", bi.biXPelsPerMeter);
	printf ("bi.biYPelsPerMeter	 = %d\n", bi.biYPelsPerMeter);
	printf ("bi.biClrUsed   	 = %d\n", bi.biClrUsed);
	printf ("bi.biClrImportant	 = %d\n", bi.biClrImportant);
	
	LineBytes = (unsigned long) bi.biWidth * bi.biBitCount;
	ImgSize   = (unsigned long) LineBytes  * bi.biHeight;
	printf ("ImgSize = %d\n", ImgSize);	

	if(bi.biClrUsed != 0)
	{
		NumColors = (unsigned long) bi.biClrUsed;
	}
	else
	{
	        switch(bi.biBitCount)
	        {
		       	case 1:
	        	    NumColors=2;
	        	    break;
	        	case 4:
	        	    NumColors=16;
	        	    break;
	        	case 8:
	        	    NumColors=256;
	        	    break;
	        	case 24:
	        	    NumColors=0;
	        	    break;
	              default:
	                  fclose(f);
	                  return 1; 
        	}
        }	

	if(bf.bfOffBits != (unsigned long) (NumColors * sizeof(RGBQUAD) + 14+40))
	{
		printf ("Invalid color numbers!\n");
		fclose(f);
		return 1; 
	}

	sd256_bitmap_len = (unsigned long)(NumColors*sizeof(RGBQUAD))+ImgSize;
	printf ("sd256_bitmap_len = %d\n", sd256_bitmap_len);
	
	temp[0] = 0x3e;
	temp[1] = 0x00;
	temp[2] = (char) (sd256_bitmap_len & 0xff00);
	temp[3] = (char) (sd256_bitmap_len & 0x00ff);
	
	temp[4] = (char) (bi.biWidth & 0xff00);
	temp[5] = (char) (bi.biWidth & 0x00ff);
	temp[6] = (char) (bi.biHeight & 0xff00);
	temp[7] = (char) (bi.biHeight & 0x00ff);

	if((sd256_bitmap = (char *) malloc (sd256_bitmap_len))==NULL)
	{
		printf ("Error alloc memory!\n");
		fclose(f);
		free (sd256_bitmap);	
		return 1; 
	}
	
	if((sd256_YUV = (char *) malloc (sd256_bitmap_len))==NULL)
	{
		printf ("Error alloc memory!\n");
		fclose(f);
		free (sd256_bitmap);	
		return 1; 
	}

	fseek (f, 14+40, SEEK_SET);
	n = fread (sd256_bitmap, 1, sd256_bitmap_len, f);
	printf ("n = %d\n", n);
	fclose (f);

	fp = fopen (HeaderFileName, "w+t");    
        
        for (i=0; i<1024; i+=4)
        {
//	        yvalue = rgb2y (sd256_bitmap[i+2], sd256_bitmap[i+1], sd256_bitmap[i]);
//		uvalue = rgb2u (sd256_bitmap[i+2], sd256_bitmap[i+1], sd256_bitmap[i]);
//		vvalue = rgb2v (sd256_bitmap[i+2], sd256_bitmap[i+1], sd256_bitmap[i]);

//		sd256_YUV[i] = 0xff;
//		sd256_YUV[i+1] = yvalue;
//		sd256_YUV[i+2] = uvalue;
//		sd256_YUV[i+3] = vvalue;

		sd256_YUV[i] = 0xff;	//保留位
		sd256_YUV[i+1] = rgb2y (sd256_bitmap[i+2]/*r*/, sd256_bitmap[i+1]/*g*/, sd256_bitmap[i]/*b*/);
		sd256_YUV[i+2] = rgb2u (sd256_bitmap[i+2], sd256_bitmap[i+1], sd256_bitmap[i]);
		sd256_YUV[i+3] = rgb2v (sd256_bitmap[i+2], sd256_bitmap[i+1], sd256_bitmap[i]);

	}

//	j=1024;
//	for (i=n; i>1024; i--)
//	{
//		sd256_YUV[j] = sd256_bitmap[i];
//		j++;
//	}
	k = 1024;
    	for (i=bi.biHeight; i>0; i--)   
    	{ 
    		for (j=0; j<bi.biWidth; j++)    
    		{
    			sd256_YUV[k] = sd256_bitmap[1024+ (i-1) * bi.biWidth + j];
    			k++;
    		}
    	}
    	
        fputs ( "unsigned char bitmap[] = {", fp);
	fprintf(fp, "\n");      

	for (i=0; i<8; i++)
	{
		if (i == 4)
			fprintf(fp, "\n");      
       		if (temp[i]<=0x0f)
        		fprintf(fp, "0x0%1x, ", temp[i]);      	
		else
        		fprintf(fp, "0x%2x, ", temp[i]);          
        }		
	
	fprintf(fp, "\n");      
	
	for (i=0; i<n; i++)
	{
        	if (i < 256*4 && i % 4 == 0)
        		fprintf(fp, "\n");      
        	else if (i >= 256*4 && i % 8 == 0 )
        		fprintf(fp, "\n");      
        	
        	if (i == 256*4)
        		fprintf(fp, "\n");      
        	
        	if (sd256_YUV[i]<=0x0f)
        		fprintf(fp, "0x0%1x, ", sd256_YUV[i]);      	
		else
        		fprintf(fp, "0x%2x, ", sd256_YUV[i]);      
        }	
        fprintf(fp, "\n");       
        fputc('}', fp);               
        fputc(';', fp);               
        fclose(fp);                   
	free (sd256_bitmap);
	free (sd256_YUV);
	return 0; 
}       

int main (int argc, char *argv[])
{
	int ret;
	
	if (argc <3) {
		printf("%s <input bmp file> <output header file>\n", argv[0]);
		exit(0);
	}
	
	printf("Input file: %s\n", argv[1]);
	printf("Output file: %s\n", argv[2]);

	ret = ConvertBmpFile (argv[1], argv[2]);
	if (ret == 0)
	{
		printf ("Convert success !\n");
		return 0;
	}	
	else	
	{
		printf ("Convert fail !\n");
		return 1;
	}	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -