framebuffer 保存 bmp图片格式

    最近需要完成一个从framebuffer中进行读取,然后将内存的东西保存为bmp图片格式,我的其他博客内容对framebuffer进行详细的讲解,以及bmp的格式进行详细的讲解。

    之前从网上看到了一些保存bmp图片的代码,在本地执行都会出现问题,本人就进行了自己编写,可以指定文件的文件名和文件类型

   也可以从github中获取源码:

直接看代码:https://github.com/Guazhen/Framebuffer_shot

  

#include <linux/fb.h>
#include <stdio.h>
#include <stdint.h> 
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h> 
#include <getopt.h>
#include <strings.h>
#include <unistd.h>
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef unsigned long LONG;

typedef struct tagBITMAPFILEHEADER {
	WORD bfType;
	DWORD bfSize;
	WORD bfReserved1;
	WORD bfReserved2;
	DWORD bfOffBits; 
} __attribute__((packed)) BITMAPFILEHEADER;


typedef struct tagBITMAPINFOHEADER
{
	DWORD biSize; /*info header size in bytes*/
	DWORD biWidth; /*widht of image*/
	DWORD biHeight;/*height of image*/
	WORD biPlanes;/*number of colour planes*/ 
	WORD biBitCount;/*bits per pixel*/
	DWORD biCompression;/*compression type*/
	DWORD biSizeImage;/*image size meter*/
	DWORD biXPelsPerMeter;/*pixels per meter*/
	DWORD biYPelsPerMeter;/*pexels per meter*/
	DWORD biClrUsed;/*number of colour*/
	DWORD biClrImportant;/*important colour*/
} __attribute__((packed)) BITMAPINFOHEADER;

int output_file;
int type_file;

struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;

static const struct option long_options[]=  
{  
     {"output",1,NULL,'o'},  
     {"t",1,NULL,'t'},    
     {NULL,0,NULL,0}  
}; 

static void usage(void)  
{  
	fprintf(stderr,  
			"imax6 [option]...\n"  
			"  -o|--output               Output the filename.\n"  
			"  -t|--type               Output the type of thefilename.\n"
			"  -h|--help               help information.\n"
	       );  
};


static void image_bmp( const char *filename)
{
	printf("starting bmp..\n");
	char tmpbufilename[126] = {0};
	if( NULL != filename)
	{
		strcpy(tmpbufilename, filename);				
		strcat(tmpbufilename,".bmp");
	}else
	{
		strcpy(tmpbufilename,"screen.bmp");
	}
	
	FILE *fp;
	BITMAPFILEHEADER    bmfh;
        BITMAPINFOHEADER    bmih;

        ((unsigned char *)&bmfh.bfType)[0] = 'B';
        ((unsigned char *)&bmfh.bfType)[1] = 'M';

        bmfh.bfSize =  sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + vinfo.yres * vinfo.xres * 4;
        bmfh.bfReserved1 = 0;
        bmfh.bfReserved2 = 0;
        bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

        bmih.biSize = sizeof(BITMAPINFOHEADER);

        bmih.biWidth = vinfo.xres;
        bmih.biHeight = vinfo.yres;
        bmih.biPlanes = 1;
        bmih.biBitCount = 32;
        bmih.biCompression = 0;
        bmih.biSizeImage = 0; /*说明图像的大小,以字节为单位。当用BI_RGB格式时,总设置为0*/
        bmih.biXPelsPerMeter = 0; /*缺省值*/
        bmih.biYPelsPerMeter = 0;
        bmih.biClrUsed = 0; /*说明位图实际使用的调色板索引数,0:使用所有的调色板索引*/
        bmih.biClrImportant = 0; /*说明对图像显示有重要影响的颜色索引的数目,如果是0,表示都重要*/

	printf("tmpbufilename = %s\n",tmpbufilename);

        FILE* image_file = fopen(tmpbufilename,"a");
	if( NULL == image_file)
	{
		printf("image fopen fail\n");
	}

        fwrite(&bmfh, sizeof(BITMAPFILEHEADER),1,image_file);
        fwrite(&bmih, sizeof(BITMAPINFOHEADER),1,image_file);

        FILE *raw_file = fopen( "test.raw","rb");
	if( NULL == raw_file)	
	{
		printf("rawfile fopen fail..\n");
	}
	
	
	/*
	fgetc是一种计算机语言中的函数。意为从文件指针stream指向的文件中读取一个字符,读取一个字节后,光标位置后移一个字节。格式:int fgetc(FILE *stream);
	*/
   
     	//int ch = fgetc(raw_file);
	int ch = getc(raw_file);
	
	/*

	for(y = 0; y < vinfo.yres; y+)
	{  
		for(x = 0; x < vinfo.xres; x++)  
		{  
			long location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y + vinfo.yoffset) * finfo.line_length;             
			write(image_file, fbp + location, 4);  
		}  
	}  	
	*/
	int x, y;
   	for( y = vinfo.yres - 1; y >= 0; y--)
	{
		for(x = 0; x < vinfo.xres; x++)
		{
			/*字节数*/
			long location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y + vinfo.yoffset) * finfo.line_length;
			fseek(raw_file, location, SEEK_SET);
			ch = fgetc(raw_file);
			fputc(ch,image_file);

			ch = fgetc(raw_file);
			fputc(ch,image_file);

			ch = fgetc(raw_file);
			fputc(ch,image_file);

			ch = fgetc(raw_file);
			fputc(ch,image_file); 
		}
	}
	/*
	while( ch != EOF)
        {
		ch = fgetc(raw_file);
                fputc(ch,image_file);
		
		ch = fgetc(raw_file);
                fputc(ch,image_file);

		ch = fgetc(raw_file);
                fputc(ch,image_file);

		ch = fgetc(raw_file);
                fputc(ch,image_file);                
        }*/

        fp = popen("rm ./test.raw","r");
        pclose(fp);

	fclose(raw_file);
	fclose(image_file);
	printf("ending bmp\n");
}

int main(int argc, char **argv)
{
	int opt = 0;
	int options_index = 0;
	char *tmp = NULL;
	char filename[126] = {0};
	char type[126] = {0};

	if(argc == 1)
	{
		usage();
		return 2;	
	}
	/* 解析命令行参数*/
	while((opt=getopt_long(argc,argv,"o:t:h?",long_options,&options_index))!=EOF )  
	{  
		switch(opt)  
		{    
			case 'o': 
				output_file=1;
				sprintf(filename,"%s",optarg);
				break;  
			case 't': 
				type_file=1;
				sprintf(type,"%s",optarg);
				break;   
			case 'h':  
			case '?': 
				usage();return 2;break;  
		}  
	}
	

	int fb_fd = open("/dev/fb0",O_RDWR);
	if(fb_fd == -1)
	{
		printf("open fail..\n");
		return -1;
	}


	ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);
	ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo);

	long screensize = vinfo.yres_virtual * finfo.line_length;
	FILE *fp = popen("bash ./test.sh","r");	
	pclose(fp);

	//bmp 
	if( output_file && type_file )
	{
		if( !strcmp(type,"bmp"))	
		{
			image_bmp(filename);
		}else if( !strcmp(type,"png"))
		{
			printf("png type = %s\n",type);
		}
		else
		{
			printf("unkown\n");
		}
	
	}	
	else
	{
		usage();return 2;
	}

	close(fb_fd);

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值