Linux下BMP圖片縮放
MP是英文Bitmap(位圖)的簡寫,它是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)致了它與生俱來的缺點(diǎn)–占用磁盤空間過大。所以,目前BMP在單機(jī)上比較流行。
本示例主要實(shí)現(xiàn)24位真彩色BMP圖片的放大與縮小。采用的縮放算法為雙線性插值。
雙線性插值參考鏈接:https://blog.csdn.net/weixinhum/article/details/38963705
-
原始圖片
- 放大示例
[xsw@xsw BMP_stady]$ ./a.out 1.bmp watermark.bmp
源圖片寬:504
源圖片高:314
請(qǐng)輸入要放大或縮小的倍數(shù)(放大為正數(shù),縮小為負(fù)數(shù)):-1
放大或縮小的比例超出范圍,請(qǐng)重新輸入!
請(qǐng)輸入要放大或縮小的倍數(shù)(放大為正數(shù),縮小為負(fù)數(shù)):0.5
新圖片寬:756
新圖片高:471
縮放比例:150%
[xsw@xsw BMP_stady]$
- 縮小示例
[xsw@xsw BMP_stady]$ gcc zoom.c
[xsw@xsw BMP_stady]$ ./a.out
格式:./a.out
[xsw@xsw BMP_stady]$ ./a.out 1.bmp watermark.bmp
源圖片寬:504
源圖片高:314
請(qǐng)輸入要放大或縮小的倍數(shù)(放大為正數(shù),縮小為負(fù)數(shù)):-0.25
新圖片寬:378
新圖片高:235
縮放比例:75%
[xsw@xsw BMP_stady]$ ??
- 縮放示例代碼
/*****************************BMP圖片放大縮小************************
**
**形參:const char *new_bmp -- 縮放后的圖片名
** const char *socure_bmp -- 源圖片名
**返回值:0 -- 成功; 其它值 -- 失敗
*********************************************************************/
int BMP_ZoomInandOut(const char *new_bmp,const char *socure_bmp)
{
FILE *fp[2];
fp[0]=fopen(socure_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;
}
fread(&bmp_info,sizeof(BMP_INFO),1,fp[0]);//讀取位圖數(shù)據(jù)
unsigned long w,h;
w=bmp_info.biWidth;//源圖片寬
h=bmp_info.biHeight;//源圖片高
printf("\t源圖片寬:%d\n",w);
printf("\t源圖片高:%d\n",h);
unsigned long oneline_byte=w*3;
while(oneline_byte%4)oneline_byte++;//源圖片一行字節(jié)數(shù),不是4的倍數(shù)補(bǔ)全
float zoom_count=0;
pp:
printf("\n\t請(qǐng)輸入要放大或縮小的倍數(shù)(放大為正數(shù),縮小為負(fù)數(shù)):");
scanf("%f",&zoom_count);
if(zoom_count<=-1|| zoom_count>4)
{
printf("放大或縮小的比例超出范圍,請(qǐng)重新輸入!\n");
goto pp;
}
bmp_info.biWidth=(1+zoom_count)*w;//新圖片寬
bmp_info.biHeight=(1+zoom_count)*h;//新圖片高
unsigned long new_w=bmp_info.biWidth;//新圖片寬
unsigned long new_h=bmp_info.biHeight;//新圖片高
printf("\t新圖片寬:%d\n",new_w);
printf("\t新圖片高:%d\n", new_h);
printf("\t縮放比例:%.0f%%\n",(new_w*1.0/w)*100);
unsigned long new_oneline_byte=new_w*3;
while(new_oneline_byte%4)new_oneline_byte++;//新圖片一行字節(jié)數(shù),不是4的倍數(shù)補(bǔ)全
// printf("新圖片一行字節(jié)數(shù):%d\n",new_oneline_byte);
bmp_head.bfSize=new_oneline_byte*new_h+sizeof(BMP_HEADER)+sizeof(BMP_INFO);//圖片總大小
bmp_info.biSizeImage=new_oneline_byte*new_h;//位圖大小
fwrite(&bmp_head,sizeof(BMP_HEADER),1,fp[1]);//頭數(shù)據(jù)寫入到新的文件中
fwrite(&bmp_info,sizeof(BMP_INFO),1,fp[1]);//位圖數(shù)據(jù)寫入到新的文件中
unsigned char *newbmp_buff=(unsigned char *)malloc(new_h*new_oneline_byte);//動(dòng)態(tài)分配新圖片RGB顏色數(shù)據(jù)緩沖區(qū)
if(newbmp_buff==NULL)
{
printf("[%s line %d]動(dòng)態(tài)分配空間失敗\n",__FUNCTION__,__LINE__);
fclose(fp[0]);
fclose(fp[1]);
return 4;
}
memset(newbmp_buff, 0, new_h*new_oneline_byte);
unsigned char *bmp_buff=(unsigned char *)malloc(h*oneline_byte);//動(dòng)態(tài)分配新圖片RGB顏色數(shù)據(jù)緩沖區(qū)
if(bmp_buff==NULL)
{
printf("[%s line %d]動(dòng)態(tài)分配空間失敗\n",__FUNCTION__,__LINE__);
fclose(fp[0]);
fclose(fp[1]);
return 5;
}
memset(bmp_buff, 0, h*oneline_byte);
unsigned long rgb_data_size=0;
rgb_data_size=h*oneline_byte;//源圖片RGB顏色數(shù)據(jù)字節(jié)大小
fseek(fp[0],bmp_head.bfOffBits,SEEK_SET);//將文件指針偏移到RGB數(shù)據(jù)處
fread(bmp_buff,rgb_data_size,1,fp[0]);//讀出所有顏色數(shù)據(jù)
/************************圖像處理算法(雙線性插值)*******************************/
int i,j;
for(i=0;i;i++)>
-
主函數(shù)
int main(int argc,char **argv)
{
if(argc!=3)
{
printf("格式:./a.out \n");
return 0;
}
int stat=0;
char buff[20];
stat=BMP_ZoomInandOut(argv[1],argv[2]);
if(stat==0)
{
snprintf(buff,sizeof(buff),"eog %s",argv[1]);//字符串拼接
system(buff);//創(chuàng)建進(jìn)程
}
else printf("[%s line %d] err %d\n",__FUNCTION__,__LINE__,stat);
return 0;
}
-
BMP位圖結(jié)構(gòu)體
//位圖文件頭信息結(jié)構(gòu)定義
#pragma pack(1)
typedef struct tagBITMAPFILEHEADER {
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;
//信息頭BITMAPINFOHEADER,也是一個(gè)結(jié)構(gòu),其定義如下:
typedef struct tagBITMAPINFOHEADER {
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;
-
注:本示例運(yùn)行環(huán)境為32位redHat6.3 linux下實(shí)現(xiàn),若是64位linux系統(tǒng)需要注意結(jié)構(gòu)體大小。
審核編輯:湯梓紅
-
Linux
+關(guān)注
關(guān)注
87文章
11292瀏覽量
209323 -
WINDOWS
+關(guān)注
關(guān)注
3文章
3541瀏覽量
88622 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
6801瀏覽量
123283 -
BMP
+關(guān)注
關(guān)注
0文章
48瀏覽量
17060
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論