首页 > 系统相关 >Linux下BMP图片截图

Linux下BMP图片截图

时间:2022-12-04 10:06:25浏览次数:42  
标签:__ fp 截图 字节 bmp unsigned BMP Linux

Linux下BMP图片截图

     MP是英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式,能够被多种Windows应用程序所支持。随着Windows操作系统的流行与丰富的Windows应用程序的开发,BMP位图格式理所当然地被广泛应用。这种格式的特点是包含的图像信息较丰富,几乎不进行压缩,但由此导致了它与生俱来的缺点–占用磁盘空间过大。所以,目前BMP在单机上比较流行。

       实际产品中我们经常用到图片截取功能,本示例主要完成对BMP图片截图功能。

  •  原始图片

Linux下BMP图片截图_BMP图片

  • 程序执行效果:
[xsw@xsw BMP_stady]$ gcc screenshot.c 
[xsw@xsw BMP_stady]$ ./a.out
格式:./a.out <new.bmp> <source.bmp>
[xsw@xsw BMP_stady]$ ./a.out new.bmp watermark.bmp
源图宽:504
源图高:314

请输截取的起始坐标(x1,y1)、结束坐标(x2、y2):89 53 323 251
新图片宽:234
新图片高:198
[xsw@xsw BMP_stady]$

Linux下BMP图片截图_BMP图片_02

  •  截图示例
/*****************************截图*********************************
**
**形参:const char *new_bmp -- 截取图片名
** const char *befor_bmp --源图名
**返回值:0 -- 成功, 其它值 -- 失败
******************************************************************/
int BMP_Screenshot(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;
}
int w,h;
fread(&bmp_info,sizeof(BMP_INFO),1,fp[0]);
h=bmp_info.biHeight;
w=bmp_info.biWidth;
printf("\t\t源图宽:%d\n",w);
printf("\t\t源图高:%d\n",h);
int x1,y1,x2,y2;
int width_size;
int height_size;
pp:
printf("\n\t请输截取的起始坐标(x1,y1)、结束坐标(x2、y2):");
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
width_size=x1>x2?(x1-x2):(x2-x1);//要截取的图片宽
height_size=y1>y2?(y1-y2):(y2-y1);//要截取的图片高
int temp;
/*保证填入的坐标在源图范围之内*/
if( width_size==0 || height_size==0 ||
width_size>w || height_size>h ||
y1>h || y2>h || x1>w || x2>w ||
x1<0 || x2<0 || y1<0 ||y2<0
)
{
printf("\t输入的参数有误,请重新输入\n");
goto pp;
}
/**保证x1<x2,方便后面文件指针偏移******/
if(x1>x2)
{
temp=x1;
x1=x2;
x2=temp;
}
/**保证y1<y2,方便后面文件指针偏移******/
if(y1>y2)
{
temp=y1;
y1=y2;
y2=temp;
}
bmp_head.bfOffBits=sizeof(BMP_HEADER)+sizeof(BMP_INFO);//RGB颜色偏移地址
bmp_head.bfSize=height_size*width_size*3+bmp_head.bfOffBits;//BMP图片总大小
fwrite(&bmp_head,sizeof(BMP_HEADER),1,fp[1]);//写入头数据到新文件
bmp_info.biWidth=width_size;//新图片宽度
bmp_info.biHeight=height_size;//新图片高度
printf("\t\t新图片宽:%d\n",bmp_info.biWidth);
printf("\t\t新图片高:%d\n",bmp_info.biHeight);
int oneline_byte=bmp_info.biWidth*3;
while(oneline_byte%4)oneline_byte++;//新图片一行字节数,不是4的倍数补齐
bmp_info.biSizeImage=bmp_info.biHeight*oneline_byte;//位图大小
fwrite(&bmp_info,sizeof(BMP_INFO),1,fp[1]);//写入位图数据到新文件
int socure_oneline_byte=w*3;
while(socure_oneline_byte%4)socure_oneline_byte++;//源图片一行字节数,不是4的倍数补齐
int i,j;
int offset;
unsigned char buff[oneline_byte];//新图片一行的缓冲区
for(i=y2-1;i>=y1;i--)
{
offset=(h-1-i)*socure_oneline_byte+x1*3+bmp_head.bfOffBits;//先偏移到要截取图片的最后一行
fseek(fp[0],offset,SEEK_SET);
fread(buff,oneline_byte,1,fp[0]);//读取要截取的一行大小
fwrite(buff,oneline_byte,1,fp[1]);//写入到新文件中
}
fclose(fp[0]);
fclose(fp[1]);
return 0;
}
  •  主函数
int main(int argc,char **argv)
{
if(argc!=3)
{
printf("格式:./a.out <new.bmp> <source.bmp>\n");
return 0;
}
int stat;
char buff[20];
stat=BMP_Screenshot(argv[1],argv[2]);
if(stat>0)printf("[%s line %d] err %d\n",__FUNCTION__,__LINE__,stat);
else
{
snprintf(buff,sizeof(buff),"eog %s",argv[1]);//字符串拼接
system(buff);//创建进程
}
return 0;
}
  •  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;

在对BMP图片进行截图时需要注意的点:

 1.每一行的字节数,当行字节数不是4的倍数需要用0补齐。

 2.对于截取的图片坐标做好判断,当输入坐标不合理时应请求重新输入或退出。

 3.BMP图片RGB颜色数据读取顺序是从下往上,从左往右,图片截取时注意读写顺序。

注:以上示例均在32位 linux下实现,若是64位linux系统需要注意结构体大小。


标签:__,fp,截图,字节,bmp,unsigned,BMP,Linux
From: https://blog.51cto.com/u_15688123/5909901

相关文章

  • [Linux]-----进程信号
    文章目录​​前言​​​​一、什么是信号​​​​我们是如何得知这些信号呢?​​​​我们知道对应的信号产生时,要做什么呢?​​​​二、进程信号​​​​前台进程和后台进程​......
  • LINUX安装openssl
    openssl官网下载​​https://www.openssl.org/source/old/​​1、解压openssl包:tar-xzfopenssl-1.1.1n.tar.gz2、得到openssl-1.1.1n目录,然后进入openssl-1.1.1n目录中......
  • Linux下查看电脑硬件及系统信息
    一、查看CPU信息1.查看CPU的统计信息:       lscpu2.查看CPU的详细信息:       cat/proc/cpuinfo二、内存信息1.查看内存使用情况:       ......
  • SELinux相关包
    https://github.com/SELinuxProject/selinux/wiki#SELinuxUserspaceThisistheupstreamrepositoryforthe SecurityEnhancedLinux(SELinux) userlandlibrarie......
  • 07Linux的那点事
    使用记录【闲】磁盘占用内存占用持续记录中.........
  • 在linux虚拟机中运行python
    在linux虚拟机中运行python方法1:运用python指令运行一般情况linux系统会自动安装python所以在终端中输入python3就自动进入python的交互模式输入ctrl+z退出交互模式......
  • Linux基础-学会使用命令帮助
    概述使用whatis使用man查看命令程序路径which总结参考资料概述Linux命令及其参数繁多,大多数人都是无法记住全部功能和具体参数意思的。在linux终端,面对命令......
  • 【Linux】/proc/stat解析
    一.概述1.1CPU时间cpu指标含义user用户态时间nice用户态时间(低优先级,nice>0)system内核态时间idle空闲时间iowaitI/O等待时间irq硬中断softirq 软中断iowait......
  • 太神奇,Linux中的虚拟网络
    随着平台虚拟化的迅速发展,对公司生态系统的其他部分进行虚拟化也并不稀奇。最近的之一就是虚拟化网络。平台虚拟化的早期实现创建了虚拟NICs,但是今天,网络中更大的部分......
  • 情景linux–一张图搞懂head -n和tail -n
        转载参考:https://blog.csdn.net/signjing/article/details/69357769 总结head-nk=head-n+k,tail-nk=tail-n-k,可以简单记忆为头正尾负;无论k前面的......