framebuffer编程
来源:互联网 发布:淘宝开店在哪交保证金 编辑:程序博客网 时间:2024/05/22 04:46
博客迁移,163真不能用
解决问题:
编程时候发现,如果使用/dev/fb0来编写应用程序图片导入,当800*480大图片整屏刷新的时候,会发现图像不是一下子就出现的,而像是一卡一卡的刷新出来,如何解决该问题?
使用:
fbfd = open("/dev/fb0", O_RDWR);//打开视频驱动显示模块,以读写的方式
ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) //
ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) //获得屏幕信息,800 480 ,以及像素bit=16bit RGB565
然后
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fbfd, 0);
这个命令可以创建一个screensize大小的显存,映射到驱动下的直接显存,可读,可写,MAP_SHARED表示直接显示。
因此我们可以对该fbp地址起始位置的内存,进行屏幕显存操作,fbp表示第一个像素地址,例如,如果我们要在800*480上的屏幕全部刷黑,我们可以用
for(i=0;i<800*480;i++)
*((unsigned short int *)fbp+i)=0x0000; //这个是用short int ,16bit的数据刷
或者 for(i=0;i<800*480*2;i++) *((unsigned char *)fbp+i)=0x00; //这个用8bit 的数据刷
上面两个效果都是一样的,并且刷新屏幕的时候,屏幕图形变化非常快,但是后面这个需要注意,char的话,第一个刷的是高8位,第二个刷的是低八位。否则会出错.
如果不是复杂的数据量如:刷新屏是白、黑、红、蓝...单色,单一图像,那么使用
memset(fbp, 0xFF,screensize); //全部刷白,注意screensize=800*480*2,因为数据0xFF是char 格式的
或者和上面一样,刷单色简单数据
这样的话,屏幕变化是很快的
问题来了
如果说我要更新一张很大的图片,屏幕该如何的快速刷新呢?
方法一:
先将图片转化为const unsigned char gImage_da
然后利用循环
for(i=0;i<800*480*2;i++)
*((unsigned char*)fbp+i)=gImage_da
这样是很慢的。因为该图片是从flash程序的co
方法二:
先开一个内存buf_temp[800*480*2]; 注意该块是运行的内存块,速度很快
fdfd_tu=open("./bizi.bin", O_RDONLY); //打开一个bin格式的图片
//注意:这里第一次打开图片的时候,可能会有点慢,但是开机仅此一次比较慢,后面就快了。
fdfd_long=read(fdfd_tu,buf_temp,800*480*2); //然后读取数据到buf_temp中
memcpy(fbp,buf_temp,800*480*2); //利用memcpy拷贝内存函数,整块进行拷贝
这样速度最快。和利用命令cp ./bizi.bin /dev/fb0效果一样。
总结:
所以,如果你的内存空间足够,那么你在程序中最好开辟一块整屏大小的内存块,然后再在该内存块上进行操作,那么肯定就不会有卡的问题了,不管是用什么方法,for(),do{}while(); memset() memcpy(),都可以。只要*(unsigned char *)fbp= 指定开辟了的内存数据存放地址。
小块图片可以用const 定义的for()循环进行拷贝,不会很影响速度。
如何解决上面的开机第一次比较慢的问题:
比较两个方法:
方法一:利用open,write的正常方法
UWord8 frame_buffer[JK_LCDScreenBuffer];
UWord32 fbfd=0; Word8 *fbp = NULL;
UWord32 fbfd_tu=0,fbfd_long=0;
fbfd = open(JK_LCD_DEV, O_RDWR);
if (fbfd < 0)
{
printf("Error: cannot open framebuffer device.\n");
exit(1);
}
else
printf("Open framebuffer device /dev/fb0 successfully\n");
fbp = (char *)mmap(NULL,(size_t)JK_LCDScreenBuffer,(int)(PROT_READ | PROT_WRITE),(int)MAP_SHARED,(int)fbfd,(off_t)0);
memset(fbp, 0xFF,JK_LCDScreenBuffer);
fbfd_tu=open(JK_DiskFileNname, O_RDONLY);
fbfd_long=read(fbfd_tu,frame_buffer,JK_LCDScreenBuffer);
memcpy(fbp,frame_buffer,JK_LCDScreenBuffer);
close(fbfd_long);
close(fbfd_tu);
close(fbfd);
方法二:利用FILE文件流格式,结果同上面的一样,就是第一次打开卡,后面就不卡了。
FILE *fp_image;
FILE *fp_device;
Word8 buffer[JK_LCDScreenBuffer];
size_t len;
if ((fp_image = fopen(JK_DiskFileNname, "rb")) == NULL)
{
printf("Error: failed to open '%s'\n", JK_DiskFileNname);
return UA_ERROR;
}
if ((fp_device = fopen(JK_LCD_DEV,"wb")) == NULL)
{
printf("Error: failed to open %s\n",LCD_DEVICE_FILENAME);
fclose(fp_image);
return UA_ERROR;
}
while(!feof(fp_image))
{
len = fread(buffer, sizeof(Word8), JK_LCDScreenBuffer, fp_image);
fwrite(buffer, sizeof(Word8), len, fp_device);
}
fclose(fp_image);
fclose(fp_device);
结论:该问题不太容易解决,可以参考内核显示logo的办法,内核显示logo非常快,一开始以为是用数据.c的结构进行写入,但是发现不是,
如何在特定的位置,显示特定的小图片?
主要弄清楚,
1.你的屏是多少位的,RGB565,或RGB666,都可以使用16bit来显示一个像素的内容。
2.数据是bin 文件,还是*.c数据文件,文件的大小其实是一样的,如果从编程的角度看,还是转化为*.c来的划算,因为毕竟bin文件放在flash中占用空间要稍微大一点,不像*.c是纯数据格式编进运行文件中,但是这样也有缺点,就是最后编译的工程会增大很多。我的意思是大图片不要编译进去,但是小图片可以。
但是从方便的角度来看,还是用*.bin的格式好用,推荐!
3.open 一个bin 文件,如果你的buffer是char形式的,那么读取的就是安装char格式,一个个的读出,和定义了unsigned char 格式的*.c数据是一样的,这样就可以一对一的进行赋值了。
下面是我的一个小程序:
UWord32 JKOpenImage(Word8 *FileName,UWord32 image_w,UWord32 image_h,UWord32 Display_x,UWord32 Display_y)
要打开的图标文件名FileName, e.g "image.bin" ,该图标的像素宽度image_w,该图标的像素高度image_h
例如:48*48的图片,还有后面是要在屏幕上显示的起始位置(x,y),注意该位置相对应的原点坐标是(0,0),也即左上角位置
{
UWord8 frame_buffer[JK_LCDScreenBuffer]; //直接申请一块屏幕大小的显存,800*480*2
UWord32 fbfd=0; Word8 *fbp = NULL;
UWord32 fbfd_tu=0;
UWord32 i=0,j=0;
UWord32 image_size=0;
UWord32 image_start=0;
fbfd = open(JK_LCD_DEV, O_RDWR);
if (fbfd < 0)
{
printf("Error: cannot open framebuffer device.\n");
exit(1);
}
fbp = (char *)mmap(NULL,(size_t)JK_LCDScreenBuffer,(int)(PROT_READ | PROT_WRITE),(int)MAP_SHARED,(int)fbfd,(off_t)0);
//If the LCD is 16bits,RGB565,then the real da
image_start=(Display_x+Display_y*800)*2;
//建立一个外部变量,保存本地原来的图像
//save the local image
for(j=0;j<image_h;j++)
for(i=0;i<image_w*2;i++)
{
*(frame_save+i+2*j*image_w)=*((Word8 *)fbp+image_start+i+2*j*800);
}
-----------利用上面这句就可以保存原来的图片。其中frame_save是外部定义个一个char 变量.
//打开小图片进行显示
fbfd_tu=open(FileName,O_RDWR);
if (fbfd_tu < 0)
{
printf("Error: cannot open framebuffer device.\n");
exit(1);
}
read(fbfd_tu,frame_buffer,image_size); 将该小图片的数据读取出来,成char格式
for(j=0;j<image_h;j++)
for(i=0;i<image_w*2;i++){
*((Word8 *)fbp+image_start+2*j*800+i)=*(frame_buffer+i+2*j*image_w);
//上面的这个绝对不能有错,否则图片显示就有问题了,image_start是利用Display_x,Display_y计算出来的起始位置, 然后i没循环到一行图片数据结束,就换行,但是记住:后面的数据一定要加上2*j*image_w,数据也一定要跟上。
//*((Word8 *)fbp+image_start+2*j*800+i)=gImage_image1[i+2*j*image_w]; 这个是用*.c数据时候的用法
}
close(fbfd_tu);
close(fbfd);
return 0;
}
可以利用上面保存的frame_save变量,将我们的图片还原。
UWord32 JKReturnImage(UWord32 image_w,UWord32 image_h,UWord32 Display_x,UWord32 Display_y)
{
UWord32 fbfd=0; Word8 *fbp = NULL;
UWord32 i=0,j=0;
UWord32 image_start;
fbfd = open(JK_LCD_DEV, O_RDWR);
if (fbfd < 0)
{
printf("Error: cannot open framebuffer device.\n");
exit(1);
}
fbp = (char *)mmap(NULL,(size_t)JK_LCDScreenBuffer,(int)(PROT_READ | PROT_WRITE),(int)MAP_SHARED,(int)fbfd,(off_t)0);
image_start=(Display_x+Display_y*800)*2;
for(j=0;j<image_h;j++)
for(i=0;i<image_w*2;i++){
*((Word8 *)fbp+image_start+2*j*800+i)=*(frame_save+i+2*j*image_w);
}
memset(frame_save,0,800*480);
close(fbfd);
return 0;
}
- Framebuffer编程
- framebuffer 编程
- Framebuffer编程
- Framebuffer编程
- framebuffer 编程
- Framebuffer编程
- framebuffer编程
- Framebuffer 编程例子
- Framebuffer编程How-to
- Framebuffer编程How-to
- framebuffer的编程资料
- Framebuffer介绍与编程
- Framebuffer编程How-to
- Framebuffer应用程序编程实例
- Framebuffer编程 应用程序
- S3C2440 framebuffer编程
- 亲自动手编程 framebuffer.
- lcd framebuffer 编程
- 什么是七日年化收益率和万分收益?
- 增广路网络流算法的实现
- 数据库学习---1
- “无穷大”值的设置
- IE 浏览器下 按下enter button自动触发click事件的解决方案
- framebuffer编程
- 【codevs 1099】字串变换
- redis异常解决:jedis.exceptions.JedisDataException: ERR Client sent AUTH, but no password is set
- 手势和tableView点击冲突解决
- 实验五:用callback增强链表模块来实现命令行菜单小程序V2.8
- EventBus使用
- 升级Xode导致CocoaPods不可用,升级CocoaPods解决
- 语音识别标准中WER和SER解释
- 《Objective-C基础教程》第11章 属性