C语言实现单色位图的放大

一般网上很少有C语言实现单色位图的放大程序,下面主要是通过C来实现单色位图的放大

#define FXZOOMRATIO 5.8   //x轴放大倍数
#define FYZOOMRATIO 5.8   //y轴放大倍数


#pragma pack(push, 2)

typedef struct  
{
	WORD    bfType;
	DWORD   bfSize;
	WORD    bfReserved1;
	WORD    bfReserved2;
	DWORD   bfOffBits;
} BITMAPFILEHEADER;

typedef struct 
{
	DWORD      biSize;
	LONG       biWidth;
	LONG       biHeight;
	WORD       biPlanes;
	WORD       biBitCount;
	DWORD      biCompression;
	DWORD      biSizeImage;
	LONG       biXPelsPerMeter;
	LONG       biYPelsPerMeter;
	DWORD      biClrUsed;
	DWORD      biClrImportant;
} BITMAPINFOHEADER;


typedef struct tagRGBQUAD
{
	BYTE rgbBlue;//蓝色的亮度(值范围为0-255)
	BYTE rgbGreen;//绿色的亮度(值范围为0-255)
	BYTE rgbRed;//红色的亮度(值范围为0-255)
	BYTE rgbReserved;//保留,必须为0
}RGBQUAD;

#pragma pack(pop)


 unsigned char *pBmpBuf;   //读入图像数据的指针
 unsigned char *pNewBmpBuf;
 int	bmpWidth;		//图像的宽
 int	bmpHeight;		//图像的高
 int 	g_lineByte; 	//放大之前每行的字节数
 RGBQUAD	*pColorTable;	//颜色表指针
 int	biBitCount;		//图像类型,每像素位数
 long	newBmpWidth;	//变化后图像的宽
 long	newBmpHeight;	//变化后图像的高
 long	newLineByte; 	//变化后图像数据每行的字节数


/****************************************************************************
 *函数名称:readBmp()
 *函数参数:const char *bmpName 读入bmp格式文件的路径及名称
 *函数返回值:0为失败 1为成功
 *函数描述:给定文件的名称和路径 读入图像的位图数据,宽,高,及每个像素的位数进内存,保存在全局变量中
 *
 ***************************************************************************/
 bool readBmp(const char* bmpName)
 {
	 FILE *fp=fopen(bmpName,"rb");
	 if(fp==0)
	 {
		printf("cannot open file");
		return 0;
	 }
	 fseek(fp,sizeof(BITMAPFILEHEADER),0);
	 BITMAPINFOHEADER head;
	 fread(&head,sizeof(BITMAPINFOHEADER),1,fp);

	 /*读取位图的长宽和深度*/
	 bmpWidth = head.biWidth;
	 bmpHeight = head.biHeight;
	 biBitCount = head.biBitCount;	

	 int iexwidth = bmpWidth;
	 if(bmpWidth % 8){
		 iexwidth += 8;
	 }
	 
	 iexwidth /= 8;	 
     g_lineByte = (iexwidth + 3) & ~0x03;	//计算每行的字节数,必须是4的倍数

	 if(biBitCount == 1)
	 {
		pColorTable =(RGBQUAD *)malloc(sizeof(RGBQUAD)*2);
		fread(pColorTable,sizeof(RGBQUAD),2,fp);	//读取调色板信息		  单色位图两个调色板
	 }
	 
	 pBmpBuf = (unsigned char *)malloc(g_lineByte *bmpHeight); //申请颜色数据区
	 fread(pBmpBuf,1,g_lineByte *bmpHeight,fp);
	 fclose(fp);

	 return 1;
 }


bool saveBmp(const char* bmpName,unsigned char *imgBuf,int width,int height,int biBitCount,RGBQUAD *pColorTable)
{
	if(!imgBuf)		//要保存的颜色数据
	   return 0;

	int colorTablesize = 0;
	if(biBitCount == 1)
	   colorTablesize =8;	//计算调色板的大小    		4*2
 
    int lineByte = newLineByte;
	
	FILE *fp = fopen(bmpName,"wb");
	if(fp == 0) return 0;
	
	BITMAPFILEHEADER fileHead;
	fileHead.bfType= 0x4d42;
	fileHead.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) + colorTablesize + lineByte *height;
	fileHead.bfReserved1 = 0;
	fileHead.bfReserved2 = 0;
	fileHead.bfOffBits = 54 +colorTablesize;
	fwrite(&fileHead,sizeof(BITMAPFILEHEADER),1,fp);
	BITMAPINFOHEADER head;
	head.biBitCount = biBitCount;
	head.biClrImportant = 0;
	head.biClrUsed = 0;
	head.biCompression = 0;
	head.biHeight = height;
	head.biPlanes =1;
	head.biSize = 40;
	head.biSizeImage = lineByte *height;
	head.biWidth = width;
	head.biXPelsPerMeter = 0;
	head.biYPelsPerMeter = 0;
	fwrite(&head,sizeof(BITMAPINFOHEADER),1,fp);

	if(biBitCount == 1){
		fwrite(pColorTable,sizeof(RGBQUAD),2,fp);
	}
	fwrite(imgBuf,height * lineByte,1,fp);
	fclose(fp);
	return 1;
} 


 /****************************************************************************
 *函数名称: bmpzoom()
 *函数参数: const char* szSrcBmp 原bmp图片的路径及名称
 
				   const char* szDstBmp 变化后保存bmp图片后的文件路径及名称
 *函数返回值:0为失败 1为成功
 *函数描述: 传入图片变化比例系数参数FXZOOMRATIO和FYZOOMRATIO 实现图片放大缩小
 *
 ***************************************************************************/
 
 bool bmpzoom(const char* szSrcBmp, const char* szDstBmp)
{	 
	readBmp(szSrcBmp);
	newBmpWidth =  (long) (bmpWidth  * FXZOOMRATIO);	//计算放大过后长宽
	newBmpHeight = (long) (bmpHeight * FYZOOMRATIO);

	int iexwidth = newBmpWidth;
	if(bmpWidth % 8){
	 iexwidth += 8;
	}

	iexwidth /= 8;	 
    newLineByte = (iexwidth + 3) & ~0x03;
	 
	pNewBmpBuf = (unsigned char*)malloc(newLineByte * newBmpHeight);	//申请新的颜色数据指针
	memset(pNewBmpBuf,0,newLineByte * newBmpHeight);	//首先全清0 纯黑

	long i,j,k;
	long i0,j0;

	if(biBitCount==1){
		for(i = 0;i < newBmpHeight;i++){
			for(j = 0; j<newBmpWidth;j++){
				
				i0 = (long)(i/FYZOOMRATIO); 
				j0 = (long)(j/FXZOOMRATIO);
				int inewbit = j % 8;
				int inewbyte = j / 8;

				int ibit =  j0 % 8;
				int ibyte = j0 / 8;

				if((j0 >=0) && (j0 < bmpWidth) && ((i0 >=0)&& (i0 <bmpHeight))){	//按照比例系数,按位取数据	   
					if(*(pBmpBuf+i0*g_lineByte+ibyte) & (unsigned char)(0x80 >> ibit)){	//白色 1
						*(pNewBmpBuf+i*newLineByte+inewbyte) |= (unsigned char)(0x80 >> inewbit);	//对应的位取1
					}
				}		 			 	
			}
		}	
	}
	 
	saveBmp(szDstBmp,pNewBmpBuf,newBmpWidth,newBmpHeight,biBitCount,pColorTable);	//将赋值过后的颜色指针保存至新图片

	if(pNewBmpBuf != NULL){
		free(pNewBmpBuf);
		pNewBmpBuf = NULL;
	}

	if(pBmpBuf != NULL){
		free(pBmpBuf);
		pBmpBuf = NULL;
	}
	
	if(biBitCount == 1){
		if(pColorTable != NULL){
			free(pColorTable);
			pColorTable = NULL;
		}	 
	} 	

	return 1;
 }






 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值