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<stdio.h>
#include<stdlib.h>
#include<string.h>
#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<new_Height;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<new_Width;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);c语言struct头文件
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;
}
⼩结:还在上⼤学,第⼀次写博客,没什么经验,可能有些地⽅描述的不是很清楚,还望谅解!