bmp_file.c

来自「做一个项目需要把点阵字库转成黑白图片」· C语言 代码 · 共 355 行

C
355
字号
#ifndef	  _BMPLOAD_H_
#define	  _BMPLOAD_H_

#include <string.h>
#include <stdio.h>
// #include <afxwin.h>
// #include <graphics.h>

#define	TRUE		1
#define	FALSE	0

typedef	unsigned char BOOL;
typedef	unsigned char UINT8;
typedef	unsigned short UINT16;
typedef	unsigned int UINT32;

/*-------------
  类型定义
  --------------*/

/*	  纹理图像结构 */
typedef	struct
{
	int	  imgWidth;	  /*	纹理宽度 */
	int	  imgHeight;   /*	 纹理高度 */
	unsigned   int	 rgbType;	/*	  每个象素对应的字节数,3:24位图,4:带alpha通道的24位图 */
	unsigned   char	  *data;   /*	 纹理数据 */
}TEXTUREIMAGE;

/*	  BMP文件头	*/
typedef	struct
{
	unsigned   short   bfType;	 /*	   文件类型	*/
	unsigned   long	  bfSize;	/*	  文件大小 */
	unsigned   short   bfReserved1;	  /*	保留位 */
	unsigned   short   bfReserved2;	  /*	保留位 */
	unsigned   long	  bfOffBits;   /*	 数据偏移位置 */
}BMPFILEHEADER;

/*	  BMP信息头	*/
typedef	struct
{
	unsigned   long	  biSize;	/*	  此结构大小 */
	long   biWidth;	  /*	图像宽度 */
	long   biHeight;   /*	 图像高度 */
	unsigned   short   biPlanes;   /*	 调色板数量	*/
	unsigned   short   biBitCount;	 /*	   每个象素对应的位数,24:24位图,32:带alpha通道的24位图 */
	unsigned   long	  biCompression;   /*	 压缩 */
	unsigned   long	  biSizeImage;	 /*	   图像大小	*/
	long   biXPelsPerMeter;/*	 横向分辨率	*/
	long   biYPelsPerMeter;/*	 纵向分辨率	*/
	unsigned   long	  biClrUsed;   /*	 颜色使用数	*/
	unsigned   long	  biClrImportant;	/*	  重要颜色数 */
}BMPINFOHEADER;



/*
#define SEARCH_DATA(Data_file) \
	while(1)						\
	{							\
		ch = fgetc(Data_file);		\
		if(ch == EOF)				\
		{						\
			FileEnd = TRUE;		\
			break;				\
		}						\
		if(ch == '0')				\
		{						\
			ch = fgetc(Data_file);	\
			if(ch == EOF)			\
			{					\
				FileEnd = TRUE;	\
				break;			\
			}					\
			if((ch == 'x') ||(ch == 'X'))	\
				break;				\
		}						\
	}							\
	if(FileEnd == TRUE)			\
		return;

*/

BOOL SEARCH_DATA(FILE *Data_file)
{
	BOOL FileEnd = FALSE;
	char ch;

	while(1)
	{
		ch = fgetc(Data_file);
		if(ch == EOF)
		{
			FileEnd = TRUE;
			break;
		}
		if(ch == '0')
		{
			ch = fgetc(Data_file);
			if(ch == EOF)
			{
				FileEnd = TRUE;
				break;
			}
			if((ch == 'x') ||(ch == 'X'))
				break;
		}
	}
	if(FileEnd == TRUE)
		return FALSE;
	else
		return TRUE;
}

UINT8 My_AtoI(char *String)
{
	UINT8 Result = 0;

	if('a' <= String[0] && String[0] <= 'f')
		Result = (String[0] - 'a' + 10) *16;
	else if('A' <= String[0] && String[0] <= 'F')
		Result = (String[0] - 'A' + 10) *16;
	else if('0' <= String[0] && String[0] <= '9')
		Result = (String[0] - '0') *16;
	
	if('a' <= String[1] && String[1] <= 'f')
		Result += String[1] - 'a' + 10;
	else if('A' <= String[1] && String[1] <= 'F')
		Result += String[1] - 'A' + 10;
	else if('0' <= String[1] && String[1] <= '9')
		Result += String[1] - '0';

	return Result;
}
	
BOOL CreatBmp(void)
{
	FILE *Exam_file;
	FILE *Create_file;
	FILE *Data_file;
	char ch[2];
	
	char Bmp_FileName[9];
	char BmpFile[0xA0];
	char BmpFile_bak[0xA0];
	char *pBmpFile;
	char *pBmpData;
	char BmpBitData[3];
	
	int Result;
	UINT16 i;
	
	memset(Bmp_FileName, 0, sizeof(Bmp_FileName));
	memset(BmpFile, 0, sizeof(BmpFile));
	memset(BmpBitData, 0, sizeof(BmpBitData));
	
	/*	  打开文件 */
	Exam_file = fopen("black.bmp", "rb");
	if (Create_file ==  NULL)
	{
		printf("Open \"black.bmp\" File Error");
		return FALSE;
	}
	rewind(Exam_file);
	Result = fread(BmpFile, sizeof(char), 0x3E, Exam_file);
	fclose(Exam_file);
	
	Data_file = fopen("S9_24Ch.dat", "rt");
	rewind(Data_file);
	
	while(1)
	{
		memset(Bmp_FileName, 0, sizeof(Bmp_FileName));
		memset(BmpBitData, 0, sizeof(BmpBitData));
		
		SEARCH_DATA(Data_file);
		Result = fgets(BmpBitData, 3, Data_file);
		SEARCH_DATA(Data_file);
		fgets(Bmp_FileName, 3, Data_file);
		strcpy(Bmp_FileName+2, BmpBitData);
		strcat(Bmp_FileName+4, ".bmp");
		
		pBmpFile = BmpFile+0x3E;
		for(i=0; i<72; i++)
		{
			SEARCH_DATA(Data_file);
			memset(BmpBitData, 0, 3);
			fgets(BmpBitData, 3, Data_file);
			
			*pBmpFile = My_AtoI(BmpBitData);
			pBmpFile += 1;
			
			if(i%3 ==2)
			{
				*pBmpFile = 0;
				pBmpFile += 1;
			}
		}
		*pBmpFile = 0;


		memset(BmpFile_bak, 0, sizeof(BmpFile_bak));
		memcpy(BmpFile_bak, BmpFile, 0x3E);
		
		pBmpFile = BmpFile+0x3E;
		pBmpData = BmpFile_bak+0x3E;
		for(i=0; i<24; i++)
		{
			*(pBmpData+i*4) = *(pBmpFile+((23-i)*4));
			*(pBmpData+i*4+1) = *(pBmpFile+((23-i)*4)+1);
			*(pBmpData+i*4+2) = *(pBmpFile+((23-i)*4)+2);
		}
		
		Create_file = fopen(Bmp_FileName, "wb");
		if (Create_file ==  NULL)
		{
			printf("Open or Create \"%s\" File Error", Bmp_FileName);
			return FALSE;
		}
		rewind(Create_file);
		// Result = fwrite(BmpFile, sizeof(char), 0x9E, Create_file);
		Result = fwrite(BmpFile_bak, sizeof(char), 0x9E, Create_file);
		
		fclose(Create_file);
	}
}

/*	  读取BMP文件创建纹理 */
BOOL LoadBmp(char *filename, TEXTUREIMAGE *textureImg)
{
	int	i, j;
	FILE *file;
	BMPFILEHEADER bmpFile;
	BMPINFOHEADER bmpInfo;
	int	pixel_size;

	/*	  初始化纹理数据 */
	textureImg->imgWidth   =   0;
	textureImg->imgHeight	=	0;
	textureImg->rgbType	  =	  0;
	if	 (textureImg->data	 !=	  NULL)
	{
		free(textureImg->data);
	}

	/*	  打开文件 */
	file   =   fopen(filename,	 "rb");
	if	 (file	 ==	  NULL)
	{
		printf("%s", "Open	 File	Error");
		return	 FALSE;
	}

	/*	  获取文件头 */
	rewind(file);
	/*	  这里是因为C中对结构体的内存对齐,所以要减去2,否则得不到正确的结果 */
	fread(&bmpFile,	  sizeof(BMPFILEHEADER)-2,	 1,	  file);
	/* 因为C语言对结构按四位对齐,所以不能直接用sizeof(BMPFILEHEADER) */
	fread(&bmpInfo,	  sizeof(BMPINFOHEADER),   1,	file);

	/*	  验证文件类型 */
	if	 (bmpFile.bfType   !=	0x4D42)
	{
		printf("%s", "File	 Type	Error");
		fclose(file);
		return	 FALSE;
	}

	/*	  获取图像色彩数 */
	pixel_size = bmpInfo.biBitCount	>> 3;

	/*	  读取文件数据 */
	textureImg->data = malloc(bmpInfo.biWidth *	bmpInfo.biHeight * pixel_size);
	if(textureImg->data	== NULL)
	{
		fclose(file);
		return	 FALSE;
	}
	rewind(file);
	fseek(file,	  54L,	 0);
	for(i =	0; i < bmpInfo.biHeight; i++)
	{
		for	  (j = 0; j	< bmpInfo.biWidth; j++)
		{
			/*	  红色分量 */
			fread(
				textureImg->data   +   (i	*	bmpInfo.biWidth	  +	  j)   *   pixel_size	+	2,
				sizeof(unsigned	  char),   1,	file);
			/*	  绿色分量 */
			fread(
				textureImg->data   +   (i	*	bmpInfo.biWidth	  +	  j)   *   pixel_size	+	1,
				sizeof(unsigned	  char),   1,	file);
			/*	  蓝色分量 */
			fread(textureImg->data	 +	 (i	  *	  bmpInfo.biWidth	+	j)	 *	 pixel_size	  +	  0,
				sizeof(unsigned	  char),   1,	file);
			/*	  Alpha分量	*/
			if	 (pixel_size   ==	4)
			{
				fread(textureImg->data	 +	 (i	  *	  bmpInfo.biWidth	+	j)	 *	 pixel_size	  +	  3,
				sizeof(unsigned	  char), 1,	file);
			}
		}
	}

	/*	  记录图像相关参数 */
	textureImg->imgWidth   =   bmpInfo.biWidth;
	textureImg->imgHeight	=	bmpInfo.biHeight;
	textureImg->rgbType	  =	  pixel_size;
	fclose(file);
	return	 TRUE;
}

#endif



void main()
{
	CreatBmp();
	getch();
#if 0
	int	  x,y,i;
	unsigned   char	  b,g,r,t;
	FILE   *bmp;
	int	  device=VGA,mode=VGAHI;
	initgraph(&device,&mode,"");
	settextstyle(TRIPLEX_FONT,HORIZ_DIR,1);
	setfillstyle(SOLID_FILL,0);
	setcolor(7);
	bmp=fopen("Sel.bmp","rb");	/*	此处打开一个(BMP格式图形320*200)	*/
	fseek(bmp,54,SEEK_SET);
	for	  (i=0;i<16;i++)
	{
		setpalette(i,i);
		b=fgetc(bmp)>>2;
		g=fgetc(bmp)>>2;
		r=fgetc(bmp)>>2;
		t=fgetc(bmp)>>2;
		setrgbpalette(i,r,g,b);
	}
	for(y=0;y<200;y++)
		for(x=0;x<160;x++)
		{
			t=fgetc(bmp);
			putpixel(x*2+160,339-y,t>>4);
			putpixel(x*2+161,339-y,t&15);
		}
	fclose(bmp);
	getch();
	closegraph();
#endif
}

⌨️ 快捷键说明

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