• 问题描述:

编写一个程序,可以在命令行输入参数,完成指定文件的缩放,并存储到新文件,命令行参数如下

zoom file1.bmp 200 file2.bmp

第一个参数为可执行程序名称,第二个参数为原始图像文件名,第三个参数为缩放比例(百分比),第四个参数为新文件名

  • 问题分析:
  1. 综述:

要实现对bmp图像操作,首先要知道bmp图像的存储机理(图像信息如何以二进制信息存储)及文件包含的内容;其次知晓基本的图像缩放算法即可;最后要知晓如何读取和存储文件信息。

  1. 实现时的困难:

    1. 定义何种类型变量?
    2. 文件大小如何读取、计算?
    3. 像素信息如何读取、写入?
  2. 对应解决方案
    1. 首先创建全局变量,如src_:原图宽高;dst_:缩放后宽高;各函数都可对其进行访问;其次用一个字符数组typedef unsigned char pixel[3];存储一个像素的RGB信息;对于缩放比例用double height_zoom_rate,width_zoom_rate;操作更精准,计算缩放后像素用类型转换即可,如:dst_width=(int)(width_zoom_rate*src_width); 而在访问文件文件头和信息头时,定义unsigned char *buf=NULL,*bui=NULL;方便逐个字节访问,也可以处理小端对齐。
    2. 即如何根据字节小端对齐计算文件大小;前面已经用buf、bui逐个访问文件头,信息头的每个字节数据,故如:b_size=bui[23]*16*16*16*16*16*16+bui[22]*16*16*16*16+bui[21]*16*16+bui[20];

可以读取图像大小;而:

f_size=dst_width*dst_height+54;则可计算操作后的文件大小

  1. 每个像素的RGB信息各占一个字节,用fgetc即可读取每个字节。读取完一行的像素后,通过计算填充字节个数(pad_num=(4-(src_width*3)%4)%4;),再用fgetc读掉填充字节,即可读取下一行。写入时采用三个字节为一组(即一个像素的RGB信息),结合最近邻插入法用fwrite写入fwrite(&info[si*src_width+sj],sizeof(pixel),1,fp_n);

再用fputc(0,fp_n)写入填充字节数。

#define _CRT_SECURE_NO_WARNINGS
#include"bmp.h"extern double height_zoom_rate,width_zoom_rate;int main(int argc, char* argv[]) {//打开文件 FILE*fp=fopen(argv[1],"rb"),*fp_n = fopen(argv[3], "wb");//读取文件头、信息头 read_bmp_head(fp);//读取像素信息 read_bmp_data(fp);//计算长宽缩放比例 width_zoom_rate=height_zoom_rate=(atoi(argv[2]) /100.0);//结合最近邻插入法写入缩放后的图像信息 write_data(fp_n);//展示操作好的图像信息 read_bmp_head(fp_n);//关闭两个图像文件 fclose(fp);fclose(fp_n);return 0;
}
/*头文件使用说明:
在主程序中:extern double height_zoom_rate,width_zoom_rate;并赋值方可正常运行
包含三个函数:
void read_bmp_head(FILE*fp);
void read_bmp_data(FILE*fp);
void write_data(FILE* fp_n);
*/
#include<stdio.h>
#include<stdlib.h>
//改对取模数为1个字节(默认为8,只可是2^n)
#pragma pack(1)
//存储一个像素信息的三元素字符数组
typedef unsigned char pixel[3];
//文件头信息
typedef struct tagBITMAPFILEHEADER
{unsigned short bfType;      //保存图片类型。 'BM'(1-2字节) unsigned long bfSize;   //位图文件的大小,以字节为单位(3-6字节,低位在前)unsigned short bfReserved1;//位图文件保留字,必须为0(7-8字节)unsigned short bfReserved2;//位图文件保留字,必须为0(9-10字节)unsigned long bfOffBits;  //RGB数据偏移地址,位图数据的起始位置,以相对于位图(11-14字节,低位在前)
}BITMAP_FILE_HEADER;
//信息头信息
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字节)
}BITMAP_INFO_HEADER;//全局变量说明:src_:原图宽高;dst_:缩放后宽高;pad_num:每行补齐空字节数;
//f_size: bfSize; b_size: biSizeImage; _zoom_rate: 宽高缩放倍数;sign:是否没计算过宽高标志
int sign1=1;
int src_width,src_height,dst_width,dst_height;
int pad_num,f_size,b_size;
double height_zoom_rate,width_zoom_rate;
unsigned char *buf=NULL,*bui=NULL;
//创建两个结构体存储文件头和信息头信息
BITMAP_FILE_HEADER file_head;
BITMAP_INFO_HEADER info_head;
//info指向像素信息的头地址,以info[i](=*(info+i))访问第i个像素
pixel *info=NULL;//读取文件头和信息头的信息
void read_bmp_head(FILE*fp){if ( fp == NULL ) {printf("file doesn't exist!\n");exit(0);}rewind(fp); //读取信息 fread(&file_head, sizeof(BITMAP_FILE_HEADER), 1, fp);fread(&info_head, sizeof(BITMAP_INFO_HEADER), 1, fp);//因为信息是小端对齐,以字节为单位方便读取 buf=(unsigned char*)&file_head;printf("\nbfType:\t\t%c %c",buf[1],buf[0]);f_size=buf[5]*16*16*16*16*16*16+buf[4]*16*16*16*16+buf[3]*16*16+buf[2];printf("\nbfSize:\t\t%02x %02x %02x %02x   ----   %d",buf[5],buf[4],buf[3],buf[2],f_size);printf("\nbfReserved1:\t%02x %02x\nbfReserved2:\t%02x %02x",buf[7],buf[6],buf[9],buf[8]);printf("\nbf0ffbits:\t%02x %02x %02x %02x",buf[13],buf[12],buf[11],buf[10]); printf("\n\n"); bui=(unsigned char*)&info_head;printf("\nbiSize:\t\t%02x %02x %02x %02x",bui[3],bui[2],bui[1],bui[0]);src_width=bui[7]*16*16*16*16*16*16+bui[6]*16*16*16*16+bui[5]*16*16+bui[4];src_height=bui[11]*16*16*16*16*16*16+bui[10]*16*16*16*16+bui[9]*16*16+bui[8];printf("\nbiWidth:\t%02x %02x %02x %02x   ----   %d",bui[7],bui[6],bui[5],bui[4],src_width);printf("\nbiHeight:\t%02x %02x %02x %02x   ----   %d",bui[11],bui[10],bui[9],bui[8],src_height);printf("\nbiPlans:\t%02x %02x",bui[13],bui[12]);printf("\nbiBitCount:\t%02x %02x",bui[15],bui[14]);printf("\nbiCompression:\t%02x %02x %02x %02x",bui[19],bui[18],bui[17],bui[16]);b_size=bui[23]*16*16*16*16*16*16+bui[22]*16*16*16*16+bui[21]*16*16+bui[20];printf("\nbiSizeImage:\t%02x %02x %02x %02x   ----   %d",bui[23],bui[22],bui[21],bui[20],b_size);printf("\nbiXPelsPerMeter:%02x %02x %02x %02x",bui[27],bui[26],bui[25],bui[24]);printf("\nbiYPelsPerMeter:%02x %02x %02x %02x",bui[31],bui[30],bui[29],bui[28]);printf("\nbiClrUsed:\t%02x %02x %02x %02x",bui[35],bui[34],bui[33],bui[32]);printf("\nbiClrImportant:\t%02x %02x %02x %02x\n",bui[39],bui[38],bui[37],bui[36]);sign1=0;
}//将照片像素信息读取,通过全局变量info访问
void read_bmp_data(FILE*fp){void read_bmp_head(FILE*fp);if ( fp == NULL ) {printf("file doesn't exist!\n");exit(0);}//判断是否计算好了图像的长宽,没有则执行 if(sign1){rewind(fp);read_bmp_head(fp);}int i,j,k;//填充字节数 pad_num=(4-(src_width*3)%4)%4;//开辟空间 info=(pixel*)malloc(src_width*src_height*sizeof(pixel));//读取像素信息RGB for(i=0;i<src_height;i++){for(j=0;j<src_width;j++){info[i*src_width+j][0]=fgetc(fp);info[i*src_width+j][1]=fgetc(fp);info[i*src_width+j][2]=fgetc(fp);}//读掉填充字节 for(k=0;k<pad_num;k++)fgetc(fp);}}//将信息写入新文件
void write_data(FILE* fp_n) {rewind(fp_n);dst_width=(int)(width_zoom_rate*src_width);dst_height=(int)(height_zoom_rate*src_height);//文件头信息修改、拷贝(小对齐,故用&、>>位操作) int f_size=dst_width*dst_height+54,i,j,k;buf[2]=0x000000FF&f_size;buf[3]=(0x0000FF00&f_size)>>8;buf[4]=(0x00FF0000&f_size)>>16;buf[5]=(0xFF000000&f_size)>>24;for(i=0;i<14;i++)fputc(buf[i],fp_n);//信息头信息修改、拷贝 bui[4]=0x000000FF&dst_width;bui[5]=(0x0000FF00&dst_width)>>8;bui[6]=(0x00FF0000&dst_width)>>16;bui[7]=(0xFF000000&dst_width)>>24;bui[8]=0x000000FF&dst_height;bui[9]=(0x0000FF00&dst_height)>>8;bui[10]=(0x00FF0000&dst_height)>>16;bui[11]=(0xFF000000&dst_height)>>24;pad_num= (4-(dst_width*3)%4)%4;b_size=dst_height*(dst_width+pad_num)*3;bui[20]=0x000000FF&b_size;bui[21]=(0x0000FF00&b_size)>>8;bui[22]=(0x00FF0000&b_size)>>16;bui[23]=(0xFF000000&b_size)>>24; for(i=0;i<40;i++)fputc(bui[i],fp_n);int si,sj;//像素信息写入 for(i=0;i<dst_height;i++){si=i/height_zoom_rate;for(j=0;j<dst_width;j++){//最近邻插入法 sj=j/width_zoom_rate;fwrite(&info[si*src_width+sj],sizeof(pixel),1,fp_n);}for(k=0;k<pad_num;k++)fputc(0,fp_n);}/*//不行的写法!低效且数值越界 for(i=0;i<dst_height;i++){for(j=0;j<dst_width;j++){//最近邻插入法 fwrite(&info[(int)(i*src_width/height_zoom_rate+j/width_zoom_rate)],sizeof(pixel),1,fp_n);}for(k=0;k<pad_num;k++)fputc(0,fp_n);}*/
}

位图图像文件缩放-西安电子科技大学大一程序基础设计课程设计作业相关推荐

  1. C语言位图图像文件缩放(西电C程序作业3)

    3.位图图像文件缩放 涉及知识点:文件读写.结构体定义.内存管理.基本图像处理算法.命令行参数 要求: 编写一个程序,可以在命令行输入参数,完成指定文件的缩放,并存储到新文件,命令行参数如下 zoom ...

  2. 西电计算机绘图试题及答案,【图】- 西安电子科技大学2021春 计算机绘图(大作业)答 - 苏州常熟常熟周边其他教育培训 - 苏州百姓网...

    一. 简答题(20 分) 1.简述计算机绘图的应用领域(至少 5 种). 2.解释显示器中像素点.屏幕分辨率概念. 3.AutoCAD 中 zoom 和 scale 的区别是什么? 4.二维图形变换矩 ...

  3. 位图图像文件缩放(c++)

    位图图像文件缩放(c++) 前言: c语言课程设计需要实现位图图像缩放,但并没有提供很详细的位图图像的理解,所以颇费了一番功夫,这里给大家整理下以供参考,如有不当之处,还希望纠正 理解位图图像(24位 ...

  4. 山科大离散数学期末考试_西安电子科技大学网络与继续教育学院 2019学年上学期 《离散数学》期末考试试题 (......

    学习中心/函授站_ 姓 名                               学 号 西安电子科技大学网络与继续教育学院 2019学年上学期 <离散数学>期末考试试题 (综合大作 ...

  5. 程序设计基础课程设计—位图图像文件缩放

    个人博客地址:https://travis1024.github.io/ 位图图像文件缩放 1. 问题描述 编写一个程序,可以在命令行输入参数,完成指定文件的缩放,并存储到新文件,命令行参数如下: z ...

  6. 计算机网络工程本科培养计划,网络工程专业卓越计划本科培养方案2015版-西安电子科技大学计算机.doc...

    网络工程专业卓越计划本科培养方案2015版-西安电子科技大学计算机.doc 网络工程专业卓越计划本科培养方案 一.培养目标及培养模式 (一)培养目标 网络工程专业培养服务于社会主义现代化建设需要的德. ...

  7. c 程序设计语言西电科大,西安电子科技大学

    西安电子科技大学网络与继续教育学院 2020 学年下学期 <高级语言程序设计(C)>期末考试试题 (综合大作业) 一.选择题(每小题 1 分,共 20 分) 1.有下列程序 main() ...

  8. 计算机科学与技术考研双非,2021西安电子科技大学计算机科学与技术考研真题经验参考书...

    1. 考研&工作 本科双非二本,软件工程,为了提高工作起点决定考研,我选择了考研,目标是西安电子科技大学的计算机科学与技术学硕.关于考与计算机相关的还是做对口的计算机相关的工作,建议思考以下两 ...

  9. 西安电子科技大学计算机复试题目,西安电子科技大学考研复试 微机原理练习题...

    <西安电子科技大学考研复试 微机原理练习题>由会员分享,可在线阅读,更多相关<西安电子科技大学考研复试 微机原理练习题(26页珍藏版)>请在人人文库网上搜索. 1.微型计算机原 ...

  10. [渝粤教育] 西安电子科技大学 工程制图与计算机绘图 参考 资料

    教育 -工程制图与计算机绘图-章节资料考试资料-西安电子科技大学[] *****单元测验–国家制图标准的基本规定 1.[单选题]绘图比例包括原值.放大比例.缩小比例,优先选择: A.原值 B.缩小比例 ...

最新文章

  1. 分享Intel的安全运营中心最佳实践
  2. 软件工程的实践项目的自我目标
  3. java共享租车信息管理系统jsp源码
  4. Adobe reader 在打开时如何恢复上一次阅读位置
  5. 通过Ajax进行POST提交JSON类型的数据到SpringMVC Controller的方法
  6. webservice测试工具
  7. 组合总和3 leetcode 216
  8. 【CODEVS1191】数轴染色
  9. jQury+Ajax与C#后台交换数据
  10. SQL server int 转char类型
  11. 分享C#高端视频教程WPF讲座——WPF应用
  12. Ubuntu完美安装QQ
  13. 最全的数据结构和算法,不信过来看看有没有漏掉的
  14. python读取grd数据_ARWpost处理后的grd数据使用fortran来读取
  15. python3__机器学习__神经网络基础算法__偏执项b
  16. 计算机主机风扇声音大的原因,台式电脑风扇声音大怎么办?五个方法简单完美解决...
  17. linux 看usb 存储设备,找到哪个驱动器对应于Linux中的哪个USB大容量存储设备
  18. C语言单元测试---cunit(一) ---- 博客经典;
  19. 支持图灵架构和安培架构的TensorFlow Python库
  20. github工具之OA综合利用python

热门文章

  1. STS3、4某些版本资源——百度网盘下载
  2. emWin在STM32上移植OLED驱动问题(2)文字显示重叠的问题
  3. 以蛋白质功能研究为题写一篇综述论文
  4. Qt moc_xx 文件报错 suggested alternative: ‘_t‘
  5. ps设计工具经验技巧
  6. Power BI: 安装和设置网关
  7. 吹风机对头发的伤害有哪些?如何挑选一款适合自己的吹风机呢?
  8. bzoj-1132 Tro
  9. ugui 后备字体引用问题 References to other fronts in project
  10. 汽车厂家系统服务器费用,两款系统结构和服务费介绍