Linux framebuffer的应用

/*
在应用程序中,操作/dev/fb的一般步骤是:
1.打开/dev/fb设备文件。
2.用ioctrl操作取得当前显示屏幕的参数,如屏幕分辨率,每个像素点的比特数。根据屏幕参数可计算屏幕缓冲区的大小。
3.将屏幕缓冲区映射到用户空间(mmap)。
4.映射后就可以直接读写屏幕缓冲区,进行绘图和图片显示了。
*/


/*在Linux环境下,进行C语言编程,使用的库文件都在/usr/include目录下*/
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/fb.h>


int main()
{
int fb=0;
void *fb_mem;
struct fb_var_screeninfo vinfo;//描述显卡特性,通常是被用户设置
struct fb_fix_screeninfo finfo;//定义显卡硬件特性,不可改变
long int screensize=0;
/*打开设备文件*/
fb=open("/dev/fb0",O_RDWR);
/*取得屏幕相关参数*/
ioctl(fb,FBIOGET_FSCREENINFO,&finfo);//获取fb_var_screeninfo结构的信息
ioctl(fb,FBIOGET_VSCREENINFO,&vinfo);//获取fb_fix_screeninfo结构的信息
/*计算屏幕缓冲区大小*/
screensize=vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
/*映射屏幕缓冲区到用户地址空间*/
fb_mem=(char *)mmap(0,screensize,PROT_READ | PORT_WRITE,MAP_SHARED,fb,0);
/*下面可通过fbp指针读写缓冲区*/
/*..........*/
munmap(fb_mem,screensize);
close(fb);
}


下面是一个用framebuffer显示jpg格式图片的例子:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <jpeglib.h>
#include <jerror.h>


#define FB_DEV "/dev/fb0"
unsigned short RGB888toRGB565(unsigned char red,unsigned char green,unsigned char blue);
int fb_stat(int fb,int *width,int *height,int *depth);
int fb_pixel(void *fbmem,int width,int height,int x,int y,unsigned short color);


int main(int argc,char *argv[])
{
/*关于jpeg decompression的变量*/
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *infile;
unsigned char *buffer;
/*关于fb设备的变量*/
int fbdev;
char *fb_device=FB_DEV;
unsigned char *fbmem;
unsigned int screensize;
unsigned int fb_width;
unsigned int fb_height;
unsigned int fb_depth;
unsigned int x;
unsigned int y;

fbdev=open(fb_device,O_RDWR);
fb_stat(fbdev,&fb_width,&fb_height,&fb_depth);
screensize=fb_width * fb_height * fb_depth/8;
fbmem=mmap(0,screensize,PROT_READ | PROT_WRITE,MAP_SHARED,fbdev,0);

if((infile=fopen(argv[1],"rb"))==NULL)
{
fprintf(stderr,"open %s failed\n",argv[1]);
exit(-1);
}
cinfo.err=jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo,infile);
jpeg_read_header(&cinfo,TRUE);
jpeg_start_decompress(&cinfo);
if((cinfo.output_width>fb_width) || (cinfo.output_height>fb_height))
{
printf("too large JPEG file,cannot display\n");
return -1;
}

buffer=(unsigned char *)malloc(cinfo.output_width * cinfo.output_components);
y=0;
while(cinfo.output_scanline<cinfo.output_height)
{
jpeg_read_scanlines(&cinfo,&buffer,1);
unsigned short color;
for(x=0;x<cinfo.output_width;x++)
{
color=RGB888toRGB565(buffer[x*3],buffer[x*3+1],buffer[x*3+2]);
fb_pixel(fbmem,fb_width,fb_height,x,y,color);
}
y++; //next scanline
}
/*完成并且退出*/
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);

free(buffer);
fclose(infile);
munmap(fbmem,screensize);
close(fbdev);
return 0;
}
/*将24位的RGB888格式转化成16位的RGB565格式*/
unsigned short RGB888toRGB565(unsigned char red,unsigned char green,unsigned char blue)
{
unsigned short B=(blue>>3)& 0x001F;
unsigned short G=((green>>2)<<5)& 0x07E0;
unsigned short R=((red>>3)<<11)& 0xF800;
return (unsigned short)(R|G|B);
}
/*得到fb设备的长,宽和分辨率*/
int fb_stat(int fd,int *width,int *height,int *depth)
{
struct fb_fix_screeninfo fb_finfo;
struct fb_var_screeninfo fb_vinfo;
if(ioctl(fd,FBIOGET_FSCREENINFO,&fb_finfo))
{
perror("_func_");
return -1;
}
if(ioctl(fd,FBIOGET_VSCREENINFO,&fb_vinfo))
{
perror("_func_");
return -1;
}
*width=fb_vinfo.xres;
*height=fb_vinfo.yres;
*depth=fb_vinfo.bits_per_pixel;
return 0;
}
/*上色*/
int fb_pixel(void *fbmem,int width,int height,int x,int y,unsigned short color)
{
unsigned short *dst=((unsigned short *)fbmem+ y*width+x);
*dst=color;
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值