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

📄 bmpconverter.c

📁 可以将windows 24位BMP图转换为16位图的程序
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define U8 unsigned char

typedef enum
{
	STB_BMP_ARGB1555=2,
	STB_BMP_RGB888
}STB_BMP_FORMAT;

#define MAX_DEAL_BMP	100

typedef struct
{
	unsigned int offset;
	unsigned int size;
	char fname[256];
}CFG_FILE_INFO;

CFG_FILE_INFO CfgFileInfo[MAX_DEAL_BMP];

char out_bmp_format;

int GetCfgFileInfo(const char* pCfgFile)
{
	int fCount=0,cCount=0;
	char tmpch;
	
	FILE* fp=fopen(pCfgFile,"rt");

	if(fp==NULL)
	{
		printf("%s:%u\n",__FILE__,__LINE__);
		return 0;
	}
	
	printf("%s opend!\n",pCfgFile);
	
	while(!feof(fp))
	{
		tmpch=fgetc(fp);
		
		if(tmpch=='\n')
		{			
			CfgFileInfo[fCount++].fname[cCount]='\0';
			cCount=0;
		}
		else
			CfgFileInfo[fCount].fname[cCount++]=tmpch;
	}

	fclose(fp);
	return fCount;
}

void ConverBmpData(int fCount,const char* pOutFile)
{
	int i,j,k;
	FILE* fpout=fopen(pOutFile,"wb");
	FILE* fp;
	int flag=0x55AAAA55;
	int nfiles=fCount;
	int width,height,pad,fsize,data_offset;
	short bpp;
	int outbpp;
	char* psrc,*pdest;
	char* p1,*p2;
	unsigned short tmp;
	
	int outoffset=4+4+4+MAX_DEAL_BMP*8;

	printf("outoffset[%d]\n",outoffset);

	if(STB_BMP_ARGB1555==out_bmp_format)
		outbpp=2;
	else
		outbpp=3;

	for(i=0;i<fCount;i++)
	{
		fp=fopen(CfgFileInfo[i].fname,"rb");
		
		printf("正在转换第%d个文件%s...\n",i+1,CfgFileInfo[i].fname);
			
		if(fp==NULL)
		{
			printf("%s:%u\n",__FILE__,__LINE__);
			return;
		}

		fseek(fp,0,SEEK_END);

		fsize=ftell(fp);
		
		printf("fsize==%d\n",fsize);
		
		psrc=malloc(fsize);

		if(psrc==NULL)
			printf("%s:%u\n",__FILE__,__LINE__);
		
		fseek(fp,0,SEEK_SET);
		
		fread(psrc,fsize,1,fp);

		fclose(fp);

		memcpy(&width,psrc+18,4);
		memcpy(&height,psrc+22,4);
		memcpy(&data_offset,psrc+10,4);
		memcpy(&bpp,psrc+28,2);

		printf("width[%d]\n",width);
		printf("height[%d]\n",height);
		printf("data_offset[%d]\n",data_offset);
		printf("bpp[%d]\n",bpp);

		pad=(4-((width*bpp/8)%4))%4;//padding size

		printf("pad[%d]\n",pad);

		pdest=malloc(data_offset+width*height*outbpp);
				
		if(pdest==NULL)
			printf("%s:%u\n",__FILE__,__LINE__);
		
		memcpy(pdest,psrc,data_offset);//copy bmp header

		p2=pdest+data_offset;

		if(bpp==16)
		{
			for(j=height-1;j>=0;j--)
			{
				p1=psrc+data_offset+j*width*2+j*pad;
				
				for(k=0;k<width*2;k++)
				{					
					if(STB_BMP_ARGB1555==out_bmp_format)
					{
						*p2=*p1++;
					}
/*
					else if(STB_BMP_ARGB4444==out_bmp_format)
					{
						*p2=*p1++;
						if((k%2)==1)
							*p2|= 0xF0;
						p2++;
					}
*/
				}
			}
		}

		else if(bpp==24)
		{
			for(j=height-1;j>=0;j--)
			{
				p1=psrc+data_offset+j*width*3+j*pad;

				for(k=0;k<width;k++)
				{			
					/*windows bmp is saved top_down,so the sequence is b-g-r*/
					/*warning!!!
					++ oprator  actions only 1 times for one varaint  within a line!
					*/
					if(STB_BMP_ARGB1555==out_bmp_format)
					{
						tmp = 0;
						tmp|= ((*(p1++) & 0xF8) >> 3);//b
						tmp|= ((*(p1++) & 0xF8) << 2);//g
						tmp|= ((*(p1++) & 0xF8) << 7);//r
						tmp|=0x8000;
						*p2++=(U8)(tmp&0x00ff);
						*p2++=(U8)((tmp&0xff00)>>8);
					}
/*
					else if(STB_BMP_ARGB4444==out_bmp_format)
					{
						*p2++=((*p1&0xF0)>>4) | (*(p1+1)&0xF0);
						*p2++=((*(p1+2)&0xF0)>>4)|0xF0;
						p1+=3;
					}
*/
					else// if(STB_BMP_RGB888==out_bmp_format)
					{
						*p2++=*p1++;
						*p2++=*p1++;
						*p2++=*p1++;
					}
				}
			}
		}
		
		CfgFileInfo[i].size=data_offset+height*width*outbpp;
	
		if(i==0)
			CfgFileInfo[i].offset=outoffset;
		else
			CfgFileInfo[i].offset=CfgFileInfo[i-1].offset+CfgFileInfo[i-1].size;
	
		*(pdest+5)=(CfgFileInfo[i].size&0xFF000000)>>24;
		*(pdest+4)=(CfgFileInfo[i].size&0x00FF0000)>>16;
		*(pdest+3)=(CfgFileInfo[i].size&0x0000FF00)>>8;
		*(pdest+2)=CfgFileInfo[i].size&0x000000FF;
		
		fseek(fpout,CfgFileInfo[i].offset,SEEK_SET);
	
		fwrite(pdest,CfgFileInfo[i].size,1,fpout);
	
		free(psrc);
	
		if(pdest!=psrc)
			free(pdest);
	
		printf("第%d个文件转换完成!\n",i+1);
	}

	fseek(fpout,0,SEEK_SET);
	
	fwrite(&flag,4,1,fpout);
	fwrite(&nfiles,4,1,fpout);
//	fwrite(&out_bmp_format,4,1,fpout);

	for(i=0;i<fCount;i++)
	{
		fwrite(&CfgFileInfo[i].offset,4,1,fpout);
		fwrite(&CfgFileInfo[i].size,4,1,fpout);
	}

	fclose(fpout);

	printf("所有文件转换完成!\n");
}

void main(int argc, char** argv)
{
	int fcount=0;
	char a;
	
	printf("定义要生成的图片格式:[1-ARGB1555,2-RGB888]\n");

	while(1)
	{
		scanf("%c",&a);
		
		if((a=='1')||(a=='2'))
		{
			getchar();
			break;
		}

		getchar();/*scanf不处理回车,只能用getch滤掉*/
		
		printf("格式有误, 请重新输入:[1-ARGB1555,2-RGB888]\n");
	}
		
	out_bmp_format=a-0x30+1;
	
	if(STB_BMP_ARGB1555==out_bmp_format)
		printf("开始批量转换ARGB1555...\n\n\n");
	else if(STB_BMP_RGB888==out_bmp_format)
		printf("开始批量转换RGB888...\n\n\n");

	{
		int i,j;
		for(i=0;i<20000;i++)
			for(j=0;j<20000;j++)
				;
	}

	fcount=GetCfgFileInfo("bmpcfg.txt");

	printf("一共%d个文件!\n",fcount);

	ConverBmpData(fcount,"bmpAll.dx");

	getch();
}

⌨️ 快捷键说明

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