linux下BMP圖片旋轉(zhuǎn)
BMP是英文Bitmap(位圖)的簡(jiǎn)寫,它是Windows操作系統(tǒng)中的標(biāo)準(zhǔn)圖像文件格式,能夠被多種Windows應(yīng)用程序所支持。隨著Windows操作系統(tǒng)的流行與豐富的Windows應(yīng)用程序的開發(fā),BMP位圖格式理所當(dāng)然地被廣泛應(yīng)用。這種格式的特點(diǎn)是包含的圖像信息較豐富,幾乎不進(jìn)行壓縮,但由此導(dǎo)致了它與生俱來(lái)的缺點(diǎn)–占用磁盤空間過大。所以,目前BMP在單機(jī)上比較流行。
在使用圖片時(shí)我們經(jīng)常需要用到旋轉(zhuǎn),本示例主要完成對(duì)BMP圖片的順時(shí)針旋轉(zhuǎn)90°和逆時(shí)針旋轉(zhuǎn)90°。
- 原始圖片
- 程序執(zhí)行效果:
[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
--------------------順時(shí)針旋轉(zhuǎn)90°----------------------
旋轉(zhuǎn)后圖片寬:314
旋轉(zhuǎn)后圖片高:504
--------------------逆時(shí)針旋轉(zhuǎn)90°----------------------
旋轉(zhuǎn)后圖片寬:314
旋轉(zhuǎn)后圖片高:504
[xsw@xsw BMP_stady]$


順時(shí)針旋轉(zhuǎn)90°示例
/***********************順時(shí)針旋轉(zhuǎn)90°**************************
**
**形參:const char *new_bmp -- 順時(shí)針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]文件打開或創(chuàng)建失敗",__FUNCTION__,__LINE__);
return 2;
}
BMP_HEADER bmp_head;
BMP_INFO bmp_info;
fread(&bmp_head,sizeof(BMP_HEADER),1,fp[0]);//讀取頭數(shù)據(jù)
if(bmp_head.bfType!=0x4d42)
{
printf("[%s line %d]圖片格式錯(cuò)誤\n",__FUNCTION__,__LINE__);
fclose(fp[0]);
fclose(fp[1]);
return 3;
}
fwrite(&bmp_head,sizeof(BMP_HEADER),1,fp[1]);//頭數(shù)據(jù)寫入到新的文件中
int w,h;//旋轉(zhuǎn)90°寬和高需要互換
fread(&bmp_info,sizeof(BMP_INFO),1,fp[0]);//讀取位圖數(shù)據(jù)
h=bmp_info.biHeight;
w=bmp_info.biWidth;
bmp_info.biWidth=h;//旋轉(zhuǎn)后圖片寬度
bmp_info.biHeight=w;//旋轉(zhuǎn)后圖片高度
fwrite(&bmp_info,sizeof(BMP_INFO),1,fp[1]);//寫入位圖數(shù)據(jù)
printf("\n--------------------順時(shí)針旋轉(zhuǎn)90°----------------------\n");
printf("\t旋轉(zhuǎn)后圖片寬:%d\n",bmp_info.biWidth);
printf("\t旋轉(zhuǎn)后圖片高:%d\n",bmp_info.biHeight);
int befor_oneline_size=w*3;//之前圖片一行的字節(jié)數(shù)
while(befor_oneline_size%4)befor_oneline_size++;//按4字節(jié)對(duì)齊
int new_oneline_size=bmp_info.biWidth*3;//旋轉(zhuǎn)后圖片一行字節(jié)數(shù)
while(new_oneline_size%4)new_oneline_size++;//按4字節(jié)對(duì)齊
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]);//補(bǔ)全為4的倍數(shù)
}
}
fclose(fp[0]);
fclose(fp[1]);
return 0;
}
;j++)>
逆時(shí)針旋轉(zhuǎn)90°示例
/***********************逆時(shí)針旋轉(zhuǎn)90°**************************
**
**形參:const char *new_bmp -- 逆時(shí)針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]文件打開或創(chuàng)建失敗",__FUNCTION__,__LINE__);
return 2;
}
BMP_HEADER bmp_head;
BMP_INFO bmp_info;
fread(&bmp_head,sizeof(BMP_HEADER),1,fp[0]);//讀取頭數(shù)據(jù)
if(bmp_head.bfType!=0x4d42)
{
printf("[%s line %d]圖片格式錯(cuò)誤\n",__FUNCTION__,__LINE__);
fclose(fp[0]);
fclose(fp[1]);
return 3;
}
fwrite(&bmp_head,sizeof(BMP_HEADER),1,fp[1]);//頭數(shù)據(jù)寫入到新的文件中
int w,h;//旋轉(zhuǎn)90°寬和高需要互換
fread(&bmp_info,sizeof(BMP_INFO),1,fp[0]);//讀取位圖數(shù)據(jù)
h=bmp_info.biHeight;
w=bmp_info.biWidth;
bmp_info.biWidth=h;//旋轉(zhuǎn)后圖片寬度
bmp_info.biHeight=w;//旋轉(zhuǎn)后圖片高度
fwrite(&bmp_info,sizeof(BMP_INFO),1,fp[1]);//寫入位圖數(shù)據(jù)
printf("\n--------------------逆時(shí)針旋轉(zhuǎn)90°----------------------\n");
printf("\t旋轉(zhuǎn)后圖片寬:%d\n",bmp_info.biWidth);
printf("\t旋轉(zhuǎn)后圖片高:%d\n",bmp_info.biHeight);
int befor_oneline_size=w*3;//之前圖片一行的字節(jié)數(shù)
while(befor_oneline_size%4)befor_oneline_size++;//按4字節(jié)對(duì)齊
int new_oneline_size=bmp_info.biWidth*3;//旋轉(zhuǎn)后圖片一行字節(jié)數(shù)
while(new_oneline_size%4)new_oneline_size++;//按4字節(jié)對(duì)齊
int i,j;
int offset_count=0;
int rgb=0;
int cnt=0;
unsigned char buff[new_oneline_size];//存放新圖片一行字節(jié)數(shù)
for(i=0;i=0;j--)
{
//先讀取最后一行的第一個(gè)像素點(diǎn)
offset_count=bmp_head.bfOffBits+i*3+j*befor_oneline_size;
fseek(fp[0],offset_count,SEEK_SET);
fread(&rgb,3,1,fp[0]);//讀取一個(gè)像素點(diǎn)數(shù)據(jù)
buff[cnt++]=(rgb)&0xff;
buff[cnt++]=(rgb>>8)&0xff;
buff[cnt++]=(rgb>>16)&0xff;
}
fwrite(buff,cnt,1,fp[1]);//將一行顏色數(shù)據(jù)寫入到新文件中
if(cnt!=new_oneline_size)//補(bǔ)全為4的整數(shù)倍
{
rgb=0;
fwrite(&rgb,new_oneline_size-cnt,1,fp[1]);
}
}
fclose(fp[0]);
fclose(fp[1]);
return 0;
}
;i++)>
- BMP位圖結(jié)構(gòu)體
#pragma pack(1) /* 必須在結(jié)構(gòu)體定義之前使用,這是為了讓結(jié)構(gòu)體中各成員按1字節(jié)對(duì)齊*/
/*圖片頭*/
typedef struct BitMapFileHEADER
{
unsigned short bfType; //保存圖片類型。 'BM'
unsigned long bfSize; //圖片文件的總大小,以字節(jié)為單位(3-6字節(jié),低位在前)
unsigned short bfReserved1;//位圖文件保留字,必須為0(7-8字節(jié))
unsigned short bfReserved2;//位圖文件保留字,必須為0(9-10字節(jié))
unsigned long bfOffBits; //RGB數(shù)據(jù)偏移地址,位圖數(shù)據(jù)的起始位置,以相對(duì)于位圖(11-14字節(jié),低位在前)//文件頭的偏移量表示,以字節(jié)為單位
}BMP_HEADER;
/*圖片信息*/
typedef struct BitMapFileInfo{
unsigned long biSize; //本結(jié)構(gòu)所占用字節(jié)數(shù)(15-18字節(jié))
unsigned long biWidth; //位圖的寬度,以像素為單位(19-22字節(jié))
unsigned long biHeight; //位圖的高度,以像素為單位(23-26字節(jié))
unsigned short biPlanes; //目標(biāo)設(shè)備的級(jí)別,必須為1(27-28字節(jié))
unsigned short biBitCount; //每個(gè)像素所需的位數(shù),必須是1(雙色)(29-30字節(jié)),4(16色),8(256色)16(高彩色)或24(真彩色)之一
unsigned long biCompression;//位圖壓縮類型,必須是0(不壓縮),(31-34字節(jié))
//1(BI_RLE8壓縮類型)或2(BI_RLE4壓縮類型)之一
unsigned long biSizeImage; //位圖的大小(其中包含了為了補(bǔ)齊行數(shù)是4的倍數(shù)而添加的空字節(jié)),以字節(jié)為單位(35-38字節(jié))
unsigned long biXPelsPerMeter;//位圖水平分辨率,每米像素?cái)?shù)(39-42字節(jié))
unsigned long biYPelsPerMeter;//位圖垂直分辨率,每米像素?cái)?shù)(43-46字節(jié))
unsigned long biClrUsed; //位圖實(shí)際使用的顏色表中的顏色數(shù)(47-50字節(jié))
unsigned long biClrImportant; //位圖顯示過程中重要的顏色數(shù)(51-54字節(jié))
}BMP_INFO;
主函數(shù)
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]);//順時(shí)針90°
if(stat)
printf("[%s line %d] err %d\n",__FUNCTION__,__LINE__,stat);
else
{
snprintf(buff,sizeof(buff),"eog %s",argv[1]);//字符串拼接
system(buff);//創(chuàng)建進(jìn)程
}
stat=BMP_antiClockWise_Revolve90(argv[1],argv[2]);//逆時(shí)針旋轉(zhuǎn)90°
if(stat)
printf("[%s line %d] err %d\n",__FUNCTION__,__LINE__,stat);
else
{
snprintf(buff,sizeof(buff),"eog %s",argv[1]);//字符串拼接
system(buff);//創(chuàng)建進(jìn)程
}
return 0;
}
在對(duì)BMP圖片進(jìn)行90°旋轉(zhuǎn)時(shí)需要注意的點(diǎn):
??1.每一行的字節(jié)數(shù),當(dāng)行字節(jié)數(shù)不是4的倍數(shù)需要用0補(bǔ)齊
??2.旋轉(zhuǎn)后的圖片的寬=原圖片的高;新圖片的高=原圖片的寬
注:以上示例均在32位redHat6.3 linux下實(shí)現(xiàn),若是64位linux系統(tǒng)需要注意結(jié)構(gòu)體大小。
-
Linux
+關(guān)注
關(guān)注
87文章
11434瀏覽量
212489 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
7037瀏覽量
124804 -
BMP
+關(guān)注
關(guān)注
0文章
48瀏覽量
17269
發(fā)布評(píng)論請(qǐng)先 登錄
BMP圖片分析軟件
bmp圖片轉(zhuǎn)換為PCB圖的軟件
嵌入式linux操作framebuffer顯示bmp圖片

Linux應(yīng)用開發(fā)-LCD顯示BMP圖片
Linux下BMP圖片添加水印

Linux下BMP圖片截圖
Linux下BMP圖片縮放

Linux開發(fā)_文件目錄操作介紹、創(chuàng)建BMP圖片

評(píng)論