一直用CSDN,觉得这个平台很不错,绝大多数信息都是正确的,一直也想有把自己解决的问题和大家分享,第一次写文章,嘿嘿。希望能帮到有用的人。

本文由完整源码,*************详细注释************,有效果图,有BMP文件格式信息

本来是课后作业,做的过程中遇到问题,网上没找到了,最后琢磨出来了,供大家分享!!!

程序运行环境:Linux操作系统下

程序功能简介:将两幅bmp图像,左右拼接合成一副bmp图像

代码背景:要将一张左眼和右眼的图像,左右合成在一起,生成的新图呈现双(左右)眼试图效果。

                因此文中left.bmp也称为左眼视图,right为右眼视图,file为双眼视图即合成的新图。

 

先将BMP文件信息放着,方便大家查看,

用的纯色图,做的实例拼接,这样能一眼看出没有任何错误:左图红,右图白。合成的图像大小可能看起来不一样,只是因为我上传的时候用的截图。

标题右图——纯白
左图——纯红

效果图:

左右拼接图

源代码如下:

#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>

//54字节文件头信息,bmp图像基本信息,用结构体变量定义
typedef struct
{
	unsigned char blue;  
	unsigned char green;
	unsigned char red;
}Pixel;
typedef struct
{
    //unsigned short bfType;       //下文重新定义此变量,因为bmp文件4字节对齐,此信息为2字节
	unsigned long bfSize;      //整个文件大小包含图像数据与54字节信息                  
	unsigned short bfReserved1;	
	unsigned short bfReserved2;
	unsigned long bfOffBits;
}BmpFileHeader;
typedef struct
{
	unsigned long biSize;
	long biWidth;                    //图像宽度,左右连接应改变此量,下文改变
	long biHeight;                   //图像高度,左右连接不改变此变量
	unsigned short biPlanes;
	unsigned short biBitCount;
	unsigned long biCompression;
	unsigned long biSizeImage;       //文件图像数据大小   
	long biXPelsPerMeter;
	long biYPelsPerMeter;
	unsigned long biClrUsed;
	unsigned long biClrImportant;
}BmpInfoHeader;


//定义BMP文件的路径
const char lfilePath[]={"left.bmp"};
const char rfilePath[]={"right.bmp"};
const char filePath[]={"binoculus.bmp"};

void main()
{
    int fp,fl,fr;                     //文件描述符,对应双眼,左眼,右眼文件
    BmpFileHeader file_head;
    BmpInfoHeader info_head;         //定义一个要使用的结构体量,内容在开头
    unsigned short bfType;           //需要重新定义的头信息
    unsigned char *lineBuf;          //搬运工具,指针
    int i,lineSize;                  //定义的整型变量

    //打开左、右眼文件,只读权限
    //打开失败输出falure!,成功输出successed!
    fl=open(lfilePath,O_RDONLY,0777);        
        if(fl<0)
  	      {
                printf("%s open falure!\n",lfilePath);
              }
	else
	    printf("%s open  lfilePath  successed!\n",lfilePath);

	fr=open(rfilePath,O_RDONLY,0777);		
	    if(fr<0)
	      {
		 printf("%s open falure!\n",rfilePath);
	      }
	else
	    printf("%s open  rfilePath  successed!\n",rfilePath);

    //创建双眼文件,创建和写权限
    fp=open(filePath,O_CREAT|O_WRONLY,0777);    
         if(fp<0)
  	     {
              printf("%s create falure!\n",filePath);       
             }
         else
	   printf("%s create  filePath  successed!\n",filePath);

    //读文件头信息到结构体-----读左眼和右眼文件都可以,本文读左眼
    //读完左眼后fl左眼文件指针指向54字节出,即第一个数据图像像素点。再对fl操作时重此处54开始
    read(fl,&bfType,sizeof(bfType));
    read(fl,&file_head,sizeof(file_head));
    read(fl,&info_head,sizeof(info_head));

    //部分变量改为双眼bmp文件信息
    
    file_head.bfSize=(file_head.bfSize*2-54);
    info_head.biSizeImage=info_head.biSizeImage*2;
    info_head.biWidth=info_head.biWidth*2;


    //将结构体信息(文件头信息)写入目标文件--双眼bmp文件信息
    //写完后fp文件指针指向54字节处,即第一个数据图像像素点。再对fp操作时重此处54开始,
    //即在进行操作为数据信息
    write(fp,&bfType,sizeof(bfType));
    write(fp,&file_head,sizeof(file_head));
    write(fp,&info_head,sizeof(info_head));
	

    //读写数据区文件信息,定义一个指针——搬运数据的工具
    //指针大小为半只眼图的一行
    lineSize=(info_head.biWidth/2)*3*sizeof(unsigned char);   
    lineBuf=(unsigned char*)malloc(lineSize);

	
	//读右眼图像数据文件时需要跳54字节的空间,因为默认重0开始(即指向头信息第一个点)
        //跳过后指向数据区,读出的数据才是正真想要的
	lseek(fr,54,SEEK_SET);

	//每次读写左、右眼文件中的一行,读biHeight次
	for(i=0;i<info_head.biHeight;i++)
	    {             
		read(fl,lineBuf,lineSize);
		write(fp,lineBuf,lineSize);
		read(fr,lineBuf,lineSize);
		write(fp,lineBuf,lineSize);
	    }

	//关闭文件和open配套
   	close(fr);
	close(fl);
	close(fp);
	
	//搭配malloc,释放指针空间
	free(lineBuf);
	printf("assignment successed!!!\n");

}

 

Logo

更多推荐