linux下bmp图片旋转 bmp是英文bitmap(位图)的简写,它是windows操作系统中的标准图像文件格式,能够被多种windows应用程序所支持。随着windows操作系统的流行与丰富的windows应用程序的开发,bmp位图格式理所当然地被广泛应用。这种格式的特点是包含的图像信息较丰富,几乎不进行压缩,但由此导致了它与生俱来的缺点–占用磁盘空间过大。所以,目前bmp在单机上比较流行。
在使用图片时我们经常需要用到旋转,本示例主要完成对bmp图片的顺时针旋转90°和逆时针旋转90°。
原始图片 程序执行效果:[xsw@xsw bmp_stady]$ gcc rivolve.c [xsw@xsw bmp_stady]$ ./a.out 格式:./a.out [xsw@xsw bmp_stady]$ ./a.out new.bmp watermark.bmp --------------------顺时针旋转90°---------------------- 旋转后图片宽:314 旋转后图片高:504--------------------逆时针旋转90°---------------------- 旋转后图片宽:314 旋转后图片高:504[xsw@xsw bmp_stady]$ 顺时针旋转90°示例
/***********************顺时针旋转90°******************************形参:const char *new_bmp -- 顺时针90°后图片** const char *befor_bmp --原始图片**返回值:0 -- 成功,其他值 -- 失败**************************************************************/int bmp_clockwise_revolve90(const char *new_bmp,const char *befor_bmp){ file *fp[2]; fp[0]=fopen(befor_bmp,rb); if(fp[0]==null) { printf([%s line %d]文件打开失败,__function__,__line__); return 1; } fp[1]=fopen(new_bmp,w+b); if(fp[1]==null) { printf([%s line %d]文件打开或创建失败,__function__,__line__); return 2; } bmp_header bmp_head; bmp_info bmp_info; fread(&bmp_head,sizeof(bmp_header),1,fp[0]);//读取头数据 if(bmp_head.bftype!=0x4d42) { printf([%s line %d]图片格式错误\n,__function__,__line__); fclose(fp[0]); fclose(fp[1]); return 3; } fwrite(&bmp_head,sizeof(bmp_header),1,fp[1]);//头数据写入到新的文件中 int w,h;//旋转90°宽和高需要互换 fread(&bmp_info,sizeof(bmp_info),1,fp[0]);//读取位图数据 h=bmp_info.biheight; w=bmp_info.biwidth; bmp_info.biwidth=h;//旋转后图片宽度 bmp_info.biheight=w;//旋转后图片高度 fwrite(&bmp_info,sizeof(bmp_info),1,fp[1]);//写入位图数据 printf(\n--------------------顺时针旋转90°----------------------\n); printf(\t旋转后图片宽:%d\n,bmp_info.biwidth); printf(\t旋转后图片高:%d\n,bmp_info.biheight); int befor_oneline_size=w*3;//之前图片一行的字节数 while(befor_oneline_size%4)befor_oneline_size++;//按4字节对齐 int new_oneline_size=bmp_info.biwidth*3;//旋转后图片一行字节数 while(new_oneline_size%4)new_oneline_size++;//按4字节对齐 int i,j; int offset_count=0; int rgb=0; for(i=w-1;i>=0;i--) { for(j=0;jbmp_info.biwidth*3) { fwrite(&rgb,new_oneline_size-bmp_info.biwidth*3,1,fp[1]);//补全为4的倍数 } } fclose(fp[0]); fclose(fp[1]); return 0;};j++)> 逆时针旋转90°示例
/***********************逆时针旋转90°******************************形参:const char *new_bmp -- 逆时针90°后图片** const char *befor_bmp --原始图片**返回值:0 -- 成功,其他值 -- 失败**************************************************************/int bmp_anticlockwise_revolve90(const char *new_bmp,const char *befor_bmp){ file *fp[2]; fp[0]=fopen(befor_bmp,rb); if(fp[0]==null) { printf([%s line %d]文件打开失败,__function__,__line__); return 1; } fp[1]=fopen(new_bmp,w+b); if(fp[1]==null) { printf([%s line %d]文件打开或创建失败,__function__,__line__); return 2; } bmp_header bmp_head; bmp_info bmp_info; fread(&bmp_head,sizeof(bmp_header),1,fp[0]);//读取头数据 if(bmp_head.bftype!=0x4d42) { printf([%s line %d]图片格式错误\n,__function__,__line__); fclose(fp[0]); fclose(fp[1]); return 3; } fwrite(&bmp_head,sizeof(bmp_header),1,fp[1]);//头数据写入到新的文件中 int w,h;//旋转90°宽和高需要互换 fread(&bmp_info,sizeof(bmp_info),1,fp[0]);//读取位图数据 h=bmp_info.biheight; w=bmp_info.biwidth; bmp_info.biwidth=h;//旋转后图片宽度 bmp_info.biheight=w;//旋转后图片高度 fwrite(&bmp_info,sizeof(bmp_info),1,fp[1]);//写入位图数据 printf(\n--------------------逆时针旋转90°----------------------\n); printf(\t旋转后图片宽:%d\n,bmp_info.biwidth); printf(\t旋转后图片高:%d\n,bmp_info.biheight); int befor_oneline_size=w*3;//之前图片一行的字节数 while(befor_oneline_size%4)befor_oneline_size++;//按4字节对齐 int new_oneline_size=bmp_info.biwidth*3;//旋转后图片一行字节数 while(new_oneline_size%4)new_oneline_size++;//按4字节对齐 int i,j; int offset_count=0; int rgb=0; int cnt=0; unsigned char buff[new_oneline_size];//存放新图片一行字节数 for(i=0;i=0;j--) { //先读取最后一行的第一个像素点 offset_count=bmp_head.bfoffbits+i*3+j*befor_oneline_size; fseek(fp[0],offset_count,seek_set); fread(&rgb,3,1,fp[0]);//读取一个像素点数据 buff[cnt++]=(rgb)&0xff; buff[cnt++]=(rgb>>8)&0xff; buff[cnt++]=(rgb>>16)&0xff; } fwrite(buff,cnt,1,fp[1]);//将一行颜色数据写入到新文件中 if(cnt!=new_oneline_size)//补全为4的整数倍 { rgb=0; fwrite(&rgb,new_oneline_size-cnt,1,fp[1]); } } fclose(fp[0]); fclose(fp[1]); return 0;};i++)> bmp位图结构体#pragma pack(1) /* 必须在结构体定义之前使用,这是为了让结构体中各成员按1字节对齐*//*图片头*/typedef struct bitmapfileheader{ 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字节,低位在前)//文件头的偏移量表示,以字节为单位}bmp_header;/*图片信息*/typedef struct bitmapfileinfo{ 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字节)}bmp_info; 主函数
int main(int argc,char **argv){ if(argc!=3) { printf(格式:./a.out \n); return 0; } int stat=0; char buff[20]; stat=bmp_clockwise_revolve90(argv[1],argv[2]);//顺时针90° if(stat) printf([%s line %d] err %d\n,__function__,__line__,stat); else { snprintf(buff,sizeof(buff),eog %s,argv[1]);//字符串拼接 system(buff);//创建进程 } stat=bmp_anticlockwise_revolve90(argv[1],argv[2]);//逆时针旋转90° if(stat) printf([%s line %d] err %d\n,__function__,__line__,stat); else { snprintf(buff,sizeof(buff),eog %s,argv[1]);//字符串拼接 system(buff);//创建进程 } return 0;} 在对bmp图片进行90°旋转时需要注意的点:
1.每一行的字节数,当行字节数不是4的倍数需要用0补齐
2.旋转后的图片的宽=原图片的高;新图片的高=原图片的宽
注:以上示例均在32位redhat6.3 linux下实现,若是64位linux系统需要注意结构体大小。
研华M2I工业设备联网解决方案 ——90%以上设备联网场景全覆盖的行业通用解决方案
高空测报灯采用了多项现代科学技术,它有哪些优势
工控机与商用台式机的八大不同点
解决数据孤岛和数据安全问题 是智慧安防发展的未来趋势
QORVO®免费工具让RF设计更容易
linux下BMP图片旋转
后摩尔时代芯片设计面临挑战
基于AI和预测维护的过程传感器
2019金融科技产业峰会之人工智能在金融领域的实践
英特尔cpu型号及分类_cpu分类及介绍_英特尔最新cpu系列
硬知识---DC-DC转换器基本原理及选型
德索讲解电动汽车高压连接器的技术条件有哪些?
大国补贴竞赛 小型经济体恐成输家
独家消息:小米集团在香港暂停交易
Sensolus将无动力资产连接到工业4.0
西部数据推出模块化高性能存储解决方案
美国著名零售公司梅西百货宣布与虚拟现实公司Marxent合作
LSI与联想宣布成立中国联合实验室
基于隔离型RS422芯片MAX1490AEPG实现高可靠性RS422通信接口的设计
对多路照明LED采用的两种调光控制电路设计