Ubuntu 9.10 实现用framebuffer显示bmp图片

在命令行下利用framebuffer显示bmp格式的图片,首先要打开framebuffer设备,ubuntu 9.10 是打开/boot/grub/grub.cfg 文件 在“linux    /boot/vmlinuz-2.6.31-22-generic root=UUID=dadb1e1d-b7b7-45c8-a031-21d2e840c608 ro   quiet splash  vga=791 " 这一行加入红字,注意不是recovery mode 。 然后重启就打开了framebuffer设备,在/dev下可以看到fb0。下面是程序代码。要注意显示的图片的位数(有16位24位和32位的)这个是显示32位bmp图片的。

#include #include #include #include #include #include #include #include #include #include #include #include #include #include static int fbfd=0; static long int screensize=0; static char *fbp=0; int x=0,y=0; long int location =0; static int xres=0,yres=0; int bits_per_pixel=0; typedef struct { char cfType[2]; // file type char cfSize[4]; // file size char cfReserved[4]; // char cfoffBits[4]; // }BITMAPFILEHEADER; //file head strucgt typedef struct { char ciSize[4]; // char ciWidth[4]; char ciHeight[4]; char ciPlanes[2]; char ciBitCount[2]; char ciCompress[4]; char ciSizeImage[4]; char ciXPelsPerMeter[4]; char ciYPelsPerMeter[4]; char ciClrUsed[4]; char ciClrImportant[4]; } BITMAPINFOHEADER; typedef struct { char rgbBlue; char rgbGreen; char rgbRed; char rgbReserved; } RGBQUAD; BITMAPFILEHEADER FileHead; BITMAPINFOHEADER InfoHead; RGBQUAD rgbquad; int show_bmp (char *bmpfile ); long chartolong(char * string, int length ); struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; int fb_init() { //struct fb_var_screeninfo vinfo; //struct fb_fix_screeninfo finfo; struct fb_bitfield red;//bitfield in fb mem if true colour struct fb_bitfield green;//else only length is significant struct fb_bitfield blue; /*open the dev */ fbfd=open("/dev/fb0",O_RDWR); if(!fbfd) { printf("erro:cannot open the dev/n"); exit(1); } else //printf("the dev is opened successfully/n"); /*get sreeen information*/ if(ioctl(fbfd,FBIOGET_FSCREENINFO,&finfo)==-1) { printf("erro reading fixed screen/n"); exit(2); } /*get variable sreen info*/ if(ioctl(fbfd,FBIOGET_VSCREENINFO,&vinfo)==-1) { printf("erro reading variable info/n"); exit(3); } /*init the parse*/ xres = vinfo.xres; yres = vinfo.yres; red = vinfo.red; green = vinfo.green; blue = vinfo.blue; bits_per_pixel=vinfo.bits_per_pixel; /*show these information*/ //printf("vifo.xres=%d/n",xres); //printf("vifo.yres=%d/n",yres); // printf("vifo.bits_per_bits=%d/n",bits_per_pixel); //printf("vifo.xoffset=%d/n",vinfo.xoffset); // printf("vifo.yoffset=%d/n",vinfo.yoffset); // printf("finfo.line_length=%d/n",finfo.line_length); /*figure out the size of screen in bytes*/ screensize=vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8; /*map the device to memory*/ fbp=(char*)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fbfd,0); if((int)fbp==-1) { printf("erro:failed to map framebuffer/n"); exit(4); } else printf ("the framebuffer device was mapped to menory successfully/n"); memset(fbp,0,screensize); return 0; } void fb_close() { munmap(fbp,screensize); close(fbfd); } long chartolong(char *string,int length) { long number; if(length<=4) { memset(&number,0x00,sizeof(long)); memcpy(&number,string,length); // } return (number); } int show_bmp(char *bmpfile) { FILE *fp; int rc; int ciBitCount,ciWidth,ciHeight; int line_x,line_y; long int location=0,BytesPerLine=0; char tmp[1024*10]; /*open the bmp file*/ fp=fopen(bmpfile,"rb"); if(fp==NULL) return (-1); //read the bmp head rc = fread(&FileHead,1,sizeof(BITMAPFILEHEADER),fp); if(rc!=sizeof(BITMAPFILEHEADER)) { fclose(fp); return(-2); } if(memcmp(FileHead.cfType,"BM",2)!=0) { fclose(fp); return(-3); } rc=fread((char*)&InfoHead,1,sizeof(BITMAPINFOHEADER),fp); if(rc!=sizeof(BITMAPINFOHEADER)) { fclose(fp); return(-4); } ciWidth=(int)chartolong(InfoHead.ciWidth,4); ciHeight=(int)chartolong(InfoHead.ciHeight,4); ciBitCount=(int)chartolong(InfoHead.ciBitCount,4); line_x=line_y=0; while(!feof(fp)) { rc=fread((char*)&rgbquad,1,sizeof(RGBQUAD),fp); if(rc!=sizeof(RGBQUAD)) break; location=(line_x+200)*bits_per_pixel/8+ (ciHeight-line_y+150)*finfo.line_length; //printf("location= %d/n", location) ; *(fbp + location + 0)=rgbquad.rgbBlue; *(fbp + location + 1)=rgbquad.rgbGreen; *(fbp + location + 2)=rgbquad.rgbRed; *(fbp + location + 3)=rgbquad.rgbReserved; line_x++ ; if(line_x==(ciWidth)) { line_x=0; line_y++ ; } } fclose(fp); return(0); } int main(int argc,char *argv[]) { int x=0; int y=0; fb_init(); show_bmp(argv[1]); return 0; }

 

追加内容: 说到framebuffer 不得不说到一个函数ioctl ,这里只是简单用了一下,ioctl中第二个参数是cmd,比如FBIOGET_FSCREENINFO,FBIOGET_VSCREENINFO,分别是获取fbfd设备的固定信息和可改变信息,FBIOPUT_VSCREENINFO 用户设置可变屏幕参数,FBIOPUTCMAP 设置屏幕颜色表,FBIOGETCMAP 获取颜色表等。

         还有个函数mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)  与之对应的是 int munmap(void *start ,size_t length)

start 是映射区开始地址, length 映射区的长度(字节),prot 期望内存保护标志,如(PROT_EXEC ,PROT_READ, PROT_WRITE, PROT_NONE) flags 指定映射对象的类型 它的值有MAP_FIXED 使用指定得映射地址,MAP_SHARED 与其它映射这个对象的进程共享映射空间,这个值不能与MAP_PRIVATE 不能同时用。MAP_LOCKED 锁定映射区的页面,防止交换内存。fd 有效文件描述词。offset 映射对象内容的起点。

mmap 成功执行返回文件映射到进程空间的地址,失败返回-1

你可能感兴趣的:(计算机软件)