Ubuntu 9.10 实现用framebuffer显示bmp图片
2012-10-18 13:51
309 查看
在命令行下利用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图片的。
[cpp] view
plaincopy
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
#include<linux/fb.h>
#include<sys/mman.h>
#include<stdlib.h>
#include<sys/ioctl.h>
#include<asm/page.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <linux/kd.h>
#include <linux/keyboard.h>
#include <termios.h>
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
mode 。 然后重启就打开了framebuffer设备,在/dev下可以看到fb0。下面是程序代码。要注意显示的图片的位数(有16位24位和32位的)这个是显示32位bmp图片的。
[cpp] view
plaincopy
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
#include<linux/fb.h>
#include<sys/mman.h>
#include<stdlib.h>
#include<sys/ioctl.h>
#include<asm/page.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <linux/kd.h>
#include <linux/keyboard.h>
#include <termios.h>
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
相关文章推荐
- Ubuntu 9.10 实现用framebuffer显示bmp图片
- S3C6410 FrameBuffer编程(六) --- 利用FrameBuffer显示图片,并实现左右、上下、180度翻转
- S3C6410 FrameBuffer编程(六) --- 利用FrameBuffer显示图片,并实现左右、上下、180度翻转
- ubuntu12.10 32位系统使用framebuffer显示24深度bmp文件
- 通过写framebuffer显示BMP图片
- 基于s3c2440 lcd framebuffer 320x240 驱动 测试 显示 320x240 16bpp bmp 图片测试程序
- linux下的framebuffer显示图片 分类: arm-linux-Ubuntu 2013-08-12 15:43 506人阅读 评论(0) 收藏
- 基于framebuffer显示图片(bmp && png)和汉字
- Linux framebuffer显示bmp图片
- 通过写framebuffer显示BMP图片
- Linux: Framebuffer显示bmp图片
- Linux framebuffer显示bmp图片
- Ubuntu Qt5 实现打开多张本地图片并显示到窗口功能
- Flex Image控件显示BMP图片实现方法
- MFC导入并显示BMP图片功能实现
- Linux framebuffer显示bmp图片
- 在发板实现24位jpg和bmp图片用手划动显示上一张与下一张图片
- MFC导入并显示BMP图片功能实现
- 通过写framebuffer显示BMP图片
- 通过写framebuffer显示BMP图片