|
楼主 |
发表于 2008-7-1 11:33:32
|
显示全部楼层
[具体情况]
framebuffer经过改动已经是8位的
GUI是DirectFB+GTK
应用程序是GTK的应用程序,可以在PC上播放录像(8位的灰度图像),已经完成,
[问题]
本来以为8位的灰度图像在8位的framebuffer上会显示得很正常,
但是把程序移植到开发板上的时候有问题了,看到的图像是云彩图像,一片一片的。
[提问]
两个问题
1,请问这是怎么回事呢?
下面的情况是我的一个推测。
我是作了一个实验,如果把24位的黑白图像变成8位的黑白图像会出现这样的问题,(从高位向低位变)正常的图像会变成云彩图像,在开发板上,Directfb+GTK的GUI先把8位的录像变成24位了,我用下面的函数画出图像。
gdk_draw_gray_image(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
0,0,720,480,GDK_RGB_DITHER_NORMAL,buf,720);
//buf是二进制的数据。
但是到显存里图像直接变成8位的了,出现数据丢失。
应该如何解决?
以下是我想的一些解决方法
1,pixbuf,这种类型是专门处理灰度图像的。
2,把RGB都设置成相等的值,再刷到内存里。
3,这个问题我到DirectFB的邮件列表里去找了,
在这里找到了一种解决的方法
http://www.mail-archive.com/directfb-us ... 00177.html
大致就是说用alpha通道解决这个问题。我一直知道的是alpha通道是用来作透明用的。
注:我直接操作显存,发现在开发板上播放录像是成功的。
问题一定在GUI这里,或者是Directfb+GTK的bug,或者程序有要修改的地方。
1,下面的程序是第一种解决方法,编译通过,运行时出问题,报错gdk_pixbuf_loader_write这里有问题难道是我用错了么?
/*这个程序只要求把视频的第一帧图像取出,并画在Drawingarea上,使用pixbuf*/
#include <gtk/gtk.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#define BUF_SIZE 720*480
static GtkWidget *window;
static GtkWidget *hbox;
static GtkWidget *drawingarea;
static GdkPixbufLoader *pixbuf_loader;
static GdkPixbuf *pixbuf;
FILE *fp;
char buf[BUF_SIZE];
gboolean draw_some( GtkWidget *widget, GdkEventExpose *event,
gpointer data )
{
/*我用下面的函数在PC上是可以画图的
gdk_draw_gray_image(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
0,0,720,480,GDK_RGB_DITHER_NORMAL,buf,720);
*/
gdk_draw_pixbuf(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
pixbuf,0,0,0,0,720,480,GDK_RGB_DITHER_NORMAL,0,0);
return TRUE;
}
int main(int argc,gchar *argv[])
{
gtk_init(&argc,&argv);
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),"一个显示视频的应用程序");
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window),720,480);
g_signal_connect(G_OBJECT(window),"delete_event",
G_CALLBACK(gtk_main_quit),NULL);
gtk_widget_show(window);
hbox=gtk_hbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window),hbox);
gtk_widget_show(hbox);
drawingarea=gtk_drawing_area_new();
gtk_box_pack_start(GTK_BOX(hbox),drawingarea,TRUE,TRUE,0);
gtk_widget_show(drawingarea);
if(! (fp=fopen("my.seq","r")))
{
printf("Error in open file my.seq\n");
exit(1);
}
memset(buf,0,BUF_SIZE*sizeof(char));
if(fread(buf,sizeof(char),BUF_SIZE,fp)<0)
{
printf("Error in read file \n");
exit(1);
}
if(!(gdk_pixbuf_loader_write( pixbuf_loader, buf, BUF_SIZE, 0 )))
{
printf("loader write error!\n");
exit(1);
}
gdk_pixbuf_loader_close (pixbuf_loader, 0 );
pixbuf = gdk_pixbuf_loader_get_pixbuf( pixbuf_loader );
g_signal_connect( G_OBJECT( drawingarea ), "expose_event",
G_CALLBACK( draw_some ), NULL );
if(fclose(fp))
{
printf("Error in close file!\n");
exit(1);
}
gtk_main();
return 0;
} |
|