开发板上显示图片

参考网址:  http://blog.csdn.net/z1179675084/article/details/14645359
                  http://hi.baidu.com/guoggn/item/636e08145b5d39fc746a8461
                  http://blog.chinaunix.net/uid-26669729-id-3077015.html
                  http://blog.csdn.net/luxiaoxun/article/details/7622988

关键:

1)字节对齐问题__attribute__((packed))   最大字节对齐

2) _attribute__((packed))的作用是告诉编译器取消结构在编译过程中的优化对齐  

3) 字节数的统计


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>  
#include <unistd.h>
#include <sys/mman.h> /*map头文件*/
#include <linux/fb.h>     
#include <fcntl.h> 
#include <string.h>  
#include <arpa/inet.h>

 //14byte文件头  
typedef struct  
{  
     unsigned char  cfType[2];//文件类型,"BM"(0x4D42)  
     unsigned int  cfSize;//文件大小(字节)  
     unsigned int cfReserved;//保留,值为0  
     unsigned int  cfoffBits;//数据区相对于文件头的偏移量(字节)  
}__attribute__((packed)) BITMAPFILEHEADER;  
/*_attribute__((packed))的作用是告诉编译器取消结构在
编译过程中的优化对齐  */

//40byte信息头  
typedef struct  
{  
     unsigned int  ciSize;//BITMAPFILEHEADER所占的字节数  
     unsigned int ciWidth;//宽度  
     unsigned int ciHeight;//高度  
     unsigned short int ciPlanes;//目标设备的位平面数,值为1  
     unsigned short int  ciBitCount;//每个像素的位数  
     char ciCompress[4];//压缩说明  
     unsigned int ciSizeImage;//用字节表示的图像大小,该数据必须是4的倍数  
     unsigned int ciXPelsPerMeter;//目标设备的水平像素数/米  
     unsigned int ciYPelsPerMeter;//目标设备的垂直像素数/米  
     unsigned int ciClrUsed; //位图使用调色板的颜色数  
     unsigned intciClrImportant; //指定重要的颜色数,当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要  
}__attribute__((packed)) BITMAPINFOHEADER;  
  
typedef struct  
{  
    unsigned char  blue;  
    unsigned char green;  
    unsigned char red;  
}__attribute__((packed)) PIXEL;//颜色模式RGB  
  
BITMAPFILEHEADER FileHead;  
BITMAPINFOHEADER InfoHead;  
static int xres = 0;  
static int yres = 0;  
static int bits_per_pixel = 0;  
static char *fb_addr = NULL;  

int show_bmp(char *picname)  
{
    FILE *fp;  
    int rc;  
    int line_x, line_y;  
    long int location = 0;
    char tmp[1024*10];
	static unsigned short b,g,r;
	static unsigned short rgb; /*2个字节*/
	PIXEL pix;  

 	fp = fopen( picname, "rb" );  
    if (fp == NULL)  
   		 {  
    		printf("open errror\n");
	        return( -1 );  
	    }  
  printf("Open OK \n");

  /* BITMAPFILEHEADER*/
   rc = fread( &FileHead, sizeof(BITMAPFILEHEADER),1, fp );  
    if ( rc != 1)  
    {  
        printf("read header error!\n");  
        fclose( fp );  
        return( -2 );  
    }  
printf("Read BITMAPFILEHEADER  OK\n");

    //检测是否是bmp图像  
    if (memcmp(FileHead.cfType, "BM", 2) != 0)  
    {  
        printf("it's not a BMP file\n");  
        fclose( fp );  
        return( -3 );  
    }  
/*BITMAPINFOHEADER*/
    rc = fread( (char *)&InfoHead, sizeof(BITMAPINFOHEADER),1, fp );  
    if ( rc != 1)  
    {  
        printf("read infoheader error!\n");  
        fclose( fp );  
        return( -4 );  
    }  
  printf("Read BITMAPINFOHEADER  OK\n");
  
    	//跳转的数据区  
    fseek(fp, FileHead.cfoffBits, SEEK_SET);  
    
    	//向framebuffer中写BMP图片  rgb高位有效
  	for  (line_y = 0; line_y<yres; line_y++)
   	 	for (line_x = 0; line_x<xres; line_x++)
   	 		{
   	 	       rc = fread(&pix , sizeof(PIXEL),1, fp);
			  	location = line_x*2+(yres-line_y)*xres*2;
   	 			r=((pix.red>>3)<<11)&0xfb80;
				g=((pix.green>>2)<<5)&0x07e0;
				b=(pix.blue>>3)&0x001f;
				rgb=r|g|b;
				*((unsigned short *)(fb_addr+location)) = rgb;
  		 	}
    fclose( fp );  
    return  0 ;  
 }  

int main(int argc, char *argv[ ])
{
      int fbfd,fb_size ;	  
     struct   fb_var_screeninfo  vinfo;   /*记录用户可修改的显示控制参数*/
     struct fb_fix_screeninfo finfo;    /*取得缓冲区的物理地址*/

	// 打开/dev/fb*设备文件
      fbfd = open("/dev/fb0",  O_RDWR|O_CREAT, S_IRWXU); 	
      if (fbfd <0 )
	      	{ 
	      		printf("open error\n");
				exit(1);
    	  	}
	
	//需要的 屏幕内存空间的字节数	,取得显示屏幕参数
	if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo))
		{  
			   printf("Error reading variable information.\n");  
		  	   exit(1);  
		 }  

   
   if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo))
	     {  
			 printf("Error reading variable information.\n");	
			 exit(1);  
		}  
  printf("R:%d,G:%d,B:%d \n", vinfo.red, vinfo.green, vinfo.blue );  
  printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );	
  
	xres=vinfo.xres;  		/*可见解析度*/
   	yres=vinfo.yres;   	
    bits_per_pixel=vinfo.bits_per_pixel;  /* 每像素位数*/ 
	fb_size=xres*yres*bits_per_pixel/8;   /*计算屏幕的总大小(字节)*/ 

// fd的内存地址空间映射到我们的程序地址空间
// void *mmap(void *start, size_t length, int prot, int flags,int fd, off_t offset);
  if ( (fb_addr  = (char *)mmap( 0, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0) )<0)
  	{
  		printf( "mmap error\n" );
		exit(1);
  	}
  
   printf("show_bmp\n");
   show_bmp( argv[1] );

     //删除对象映射  
   munmap(fb_addr, fb_size);  
   close(fbfd); 	

   return 0;
}




执行开发板程序:



图片显示:







  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值