C语言实现BMP图片的放大缩小

                                        C语言实现BMP图片的放大缩小

BMP图片简介:BMP图片是windows操作系统中的标准图像文件格式,可以分为两类:设备相关位图(DDB)和设备无关位图(DIB),使用广泛。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。

BMP图片的存储:

1:位图头文件数据结构,它包含BMP图像文件的类型、显示内容等信息;
2: 位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;
3: 调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板;
4:位图数据,这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。

C 语言程序设计思路:

1、定义一个存储头文件数据结构体
typedef struct tagBITMAPFILEHEADER
{
 unsigned short bfType;      //保存图片类型。 'BM'
 unsigned long  bfSize;      //位图文件的大小,以字节为单位(3-6字节,低位在前)
 unsigned short bfReserved1;//位图文件保留字,必须为0(7-8字节)
 unsigned short bfReserved2;//位图文件保留字,必须为0(9-10字节)
 unsigned long  bfOffBits;  //RGB数据偏移地址,位图数据的起始位置,以相对于位图(11-14字节,低位在前)
}BITMAPFILEHEADER;

2定义一个存储位图信息的结构体
typedef struct tagBITMAPINFOHEADER
{
 unsigned long  biSize;      //本结构所占用字节数(15-18字节)
 unsigned long  biWidth;     //位图的宽度,以像素为单位(19-22字节)
 unsigned long  biHeight;    //位图的高度,以像素为单位(23-26字节)
 unsigned short biPlanes;    //目标设备的级别,必须为1(27-28字节)
 unsigned short biBitCount;  //每个像素所需的位数,必须是1(双色)(29-30字节),4(16色),8(256色)16(高彩色)或24(真彩色)之一
 unsigned long  biCompression;//位图压缩类型,必须是0(不压缩),(31-34字节)
 //1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
 unsigned long  biSizeImage;  //位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位(35-38字节)
 unsigned long  biXPelsPerMeter;//位图水平分辨率,每米像素数(39-42字节)
 unsigned long  biYPelsPerMeter;//位图垂直分辨率,每米像素数(43-46字节)
 unsigned long  biClrUsed;      //位图实际使用的颜色表中的颜色数(47-50字节)
 unsigned long  biClrImportant; //位图显示过程中重要的颜色数(51-54字节)
}BITMAPINFOHEADER;

3、图片缩小的原则就是按照一定的比例从范围内的像素点中抽去像素点。而放大的原则正好相反,将一个或多个像素点按照比例复制在其周围。


程序实现:

#include
#include
#include

#pragma pack(1)  /* 必须在结构体定义之前使用,这是为了让结构体中各成员按1字节对齐*/
typedef struct tagBITMAPFILEHEADER
{
 unsigned short bfType;      //保存图片类型。 'BM'
 unsigned long  bfSize;      //位图文件的大小,以字节为单位(3-6字节,低位在前)
 unsigned short bfReserved1;//位图文件保留字,必须为0(7-8字节)
 unsigned short bfReserved2;//位图文件保留字,必须为0(9-10字节)
 unsigned long  bfOffBits;  //RGB数据偏移地址,位图数据的起始位置,以相对于位图(11-14字节,低位在前)
}BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER
{
 unsigned long  biSize;      //本结构所占用字节数(15-18字节)
 unsigned long  biWidth;     //位图的宽度,以像素为单位(19-22字节)
 unsigned long  biHeight;    //位图的高度,以像素为单位(23-26字节)
 unsigned short biPlanes;    //目标设备的级别,必须为1(27-28字节)
 unsigned short biBitCount;  //每个像素所需的位数,必须是1(双色)(29-30字节),4(16色),8(256色)16(高彩色)或24(真彩色)之一

 unsigned long  biCompression;//位图压缩类型,必须是0(不压缩),(31-34字节)
 //1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一

 unsigned long  biSizeImage;  //位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位(35-38字节)

 unsigned long  biXPelsPerMeter;//位图水平分辨率,每米像素数(39-42字节)
 unsigned long  biYPelsPerMeter;//位图垂直分辨率,每米像素数(43-46字节)
 unsigned long  biClrUsed;      //位图实际使用的颜色表中的颜色数(47-50字节)
 unsigned long  biClrImportant; //位图显示过程中重要的颜色数(51-54字节)
}BITMAPINFOHEADER;

/*
 函数名称:Bmp_Smaller
 函数功能:图片放大缩小
 参数:BITMAPFILEHEADER head,BITMAPINFOHEADER info-原照片头信息
 返回值:void
 */
void Bmp_Bigger_And_Smaller(BITMAPFILEHEADER head,BITMAPINFOHEADER info)
{
 FILE *fpr1=fopen("src.bmp","rb");
 FILE *fpw2=fopen("new.bmp","wb");
 if(fpr1==NULL||fpw2==NULL)
 {
  printf("图片打开失败!\n");
  return ;
 }
 //读取原照片的头信息
 fread(&head,sizeof(BITMAPFILEHEADER),1,fpr1);
 fread(&info,sizeof(BITMAPINFOHEADER),1,fpr1);

 unsigned int old_width=info.biWidth;//获取原图片的宽
 unsigned int old_height=info.biHeight;//获取原图片的高

 //获取原图片的位图数据
 unsigned char *src_data=malloc(old_width*old_height*3);
 fseek(fpr1,54,SEEK_SET);
 fread(src_data,old_width*old_height*3,1,fpr1);

 printf("原图片的宽:%d\n",old_width);
 printf("原图片的高:%d\n",old_height);

 //修改原照片的宽高
 unsigned int new_Width,new_Height;
 printf("请输入新图片的宽:\n");
 scanf("%d",&new_Width);
 printf("请输入新图片的高:\n");
 scanf("%d",&new_Height);
 head.bfSize=new_Width*new_Height*3+54;
 info.biWidth=new_Width;
 info.biHeight=new_Height;

 //将修改过的头信息写进新照片
 fwrite(&head,sizeof(BITMAPFILEHEADER),1,fpw2);
 fwrite(&info,sizeof(BITMAPINFOHEADER),1,fpw2);
 
 int i=0,j=0;
 unsigned long dwsrcX,dwsrcY;
 unsigned char *pucDest;
 unsigned char *pucSrc;
 unsigned char *dest_data=malloc(new_Width*new_Height*3);
 for(i=0;i  {
  dwsrcY=i*old_height/new_Height;
  pucDest=dest_data+i*new_Width*3;
  pucSrc=src_data+dwsrcY*old_width*3;
  for(j=0;j   {
   dwsrcX=j*old_width/new_Width;
   memcpy(pucDest+j*3,pucSrc+dwsrcX*3,3);//数据拷贝
  }
 }
 fseek(fpw2,54,SEEK_SET);
 fwrite(dest_data,new_Width*new_Height*3,1,fpw2);
 printf("生成新图片成功!\n");

 //释放堆空间
 free(dest_data);
 free(src_data);

 //关闭文件
 fclose(fpr1);
 fclose(fpw2);
}

/*
 函数名称:main
 函数功能:主函数
 参数:void
 返回值:int
 */
int main()
{
 //定义原照片信息结构体
 BITMAPFILEHEADER old_head;
 BITMAPINFOHEADER old_info;
 
 //将结构体清空
 memset(&old_head,0,sizeof(BITMAPFILEHEADER));
 memset(&old_info,0,sizeof(BITMAPINFOHEADER));
 

 Bmp_Bigger_And_Smaller(old_head,old_info);
 return 0; 
}


小结:还在上大学,第一次写博客,没什么经验,可能有些地方描述的不是很清楚,还望谅解!



你可能感兴趣的:(C语言)