QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: xiaocong213

gtk图像处理问题

[复制链接]
 楼主| 发表于 2005-8-6 14:44:54 | 显示全部楼层
[quote:ea53b61d6e="Kan"] 我自己的一写想法,不知道对不对,楼主看看吧。

如果是要一个空的,可以gdk_pixmap_new (drawarea->window,512,512),创建一个pixmap,然后gdk_pixbuf_get_from_drawable 得到一个pixbuf,这样子 通过gdk_pixbuf_render_threshold_alpha,就可以操作ALPHA通道了。RGB的灰度应该可以通过GC或COLORMAP来操作。通过gdk_draw_pixbuf把pixbuf中的内容写到pixmap,在通过调用gtk_widget_queue_draw_area来调用expose_event事件,在expose_event事件中通过函数gdk_draw_drawable (widget->window,gc, pixmap, .....)完成显示。
如果本身就是要读取图片的,你的办法不是挺好的。[/quote]

哇噢,显示张图片这么麻烦啊,我原来用
image = gtk_image_new_from_file ("512-512-8.tif");
pixbuf = gtk_image_get_pixbuf((GtkImage*)image);
gtk_box_pack_start(GTK_BOX(vbox),image,TRUE,TRUE,0);
gtk_widget_show(image);
这样就可以显示图片了,而且可以任意修改像素值了。
可现在我用
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 512, 512);
image = gtk_image_new_from_pixbuf(pixbuf);
gtk_box_pack_start(GTK_BOX(vbox),image,TRUE,TRUE,0);
gtk_widget_show(image);
像素值是可以修改,可是图片就显示不出来可,看到的是一片白,一定要按楼上说的显示图片吗?这也太麻烦了吧。
回复

使用道具 举报

发表于 2005-8-7 08:53:17 | 显示全部楼层
[quote:0fee5250cc="xiaocong213"]
可现在我用
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 512, 512);
image = gtk_image_new_from_pixbuf(pixbuf);
gtk_box_pack_start(GTK_BOX(vbox),image,TRUE,TRUE,0);
gtk_widget_show(image);
像素值是可以修改,可是图片就显示不出来可,看到的是一片白,一定要按楼上说的显示图片吗?这也太麻烦了吧。[/quote]
当然是白的了,你连图片都没有放进去啊。
pixbuf = gdk_pixbuf_new_from_file  (const char *filename,
                                             GError **error);

image = gtk_image_new_from_pixbuf(pixbuf);
gtk_box_pack_start(GTK_BOX(vbox),image,TRUE,TRUE,0);
gtk_widget_show(image);
用这个去试试
回复

使用道具 举报

 楼主| 发表于 2005-8-7 13:28:54 | 显示全部楼层
[quote:a6fb187e36="Kan"]
当然是白的了,你连图片都没有放进去啊。
pixbuf = gdk_pixbuf_new_from_file  (const char *filename,
                                             GError **error);

image = gtk_image_new_from_pixbuf(pixbuf);
gtk_box_pack_start(GTK_BOX(vbox),image,TRUE,TRUE,0);
gtk_widget_show(image);
用这个去试试[/quote]

楼上的与我的区别就在于
pixbuf = gdk_pixbuf_new_from_file  (const char *filename,
                                             GError **error);
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 512, 512);
其实我是不想从文件中读,我只要一个512×512RGB的空图片,正因为我不会,才想了个从文件中读的办法。我想知道我的办法为什么不行,楼上的说我连图片都没有放进去是什么意思,我在gtk_widget_show(image);前让所有的像素值设为255的话那显示出来的就应该是黑色的,但实际上还是白色的,任我怎么改像素值都一样,这是为啥?
回复

使用道具 举报

发表于 2005-8-8 08:31:06 | 显示全部楼层
[quote:a8c849f338="xiaocong213"]楼上的与我的区别就在于
pixbuf = gdk_pixbuf_new_from_file  (const char *filename,
                                             GError **error);
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 512, 512);
其实我是不想从文件中读,我只要一个512×512RGB的空图片,正因为我不会,才想了个从文件中读的办法。我想知道我的办法为什么不行,楼上的说我连图片都没有放进去是什么意思,我在gtk_widget_show(image);前让所有的像素值设为255的话那显示出来的就应该是黑色的,但实际上还是白色的,任我怎么改像素值都一样,这是为啥?[/quote]
原来,你只想要一个512×512的空图片啊,那你的方法是对的,不用从文件中读取,你说的白色的原因是因为你没有向PIXBUF中写入东西而己,就像你要一张黑纸,你现在有了一白纸,你又不把它涂黑,他怎么能变成黑纸呢?你应该向pixbuf或pixmap中画一个512*512的黑色正方形就可以了。
回复

使用道具 举报

 楼主| 发表于 2005-8-9 19:26:53 | 显示全部楼层
[quote:50e047071e="Kan"]你应该向pixbuf或pixmap中画一个512*512的黑色正方形就可以了。[/quote]
这句话说到点子上了,就是这个不会,我发现用new新建的pixbuf一开始我怎么写不进数据啊,可等我打开文件是用同样的函数可以写进去,可是显示的还是一片白。郁闷啊
回复

使用道具 举报

 楼主| 发表于 2005-8-9 19:31:40 | 显示全部楼层
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 512, 512);
for(int i=0;i<512;i++)
{
for(int j=0;j<512;j++)
{
put_pixel (pixbuf, i, j,255,255,255);
}
}
就是用上面的方法发现pixbuf里的像素值还是0,我明明都设成255了啊,难道上面的那两个循环根本就没做?
可是我在回调函数时打开文件用了一模一样的循环,像素值是改变了,可是显示还是一片白。why?
回复

使用道具 举报

发表于 2005-8-9 20:01:40 | 显示全部楼层
[quote:fa991c4728="xiaocong213"][quote:fa991c4728="Kan"]你应该向pixbuf或pixmap中画一个512*512的黑色正方形就可以了。[/quote]
这句话说到点子上了,就是这个不会,我发现用new新建的pixbuf一开始我怎么写不进数据啊,可等我打开文件是用同样的函数可以写进去,可是显示的还是一片白。郁闷啊[/quote]
不要直接往PIXBUF画东西,先向一个PIXMAP画一个方形,然后用gdk_pixbuf_get_from_drawable 把PIXMAP中的内容放到PXIBUF中,PIXMAP才是能画东西的,PIXBUF,通常用来存放数据而不是往里画东西。
回复

使用道具 举报

 楼主| 发表于 2005-8-9 22:26:42 | 显示全部楼层
研究了一个晚上还是没弄成功,决定还是用原来的土办法,虽然要多带一个图象文件,但只要三句话就可以解决问题了,将就着用吧。
我发现用pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 512, 512)后,得到的数据指针虽然不为空,但不能往里写东西,不知道为上面,我看网上好多和我一样用的,为什么他们可以而我就不可以呢,真是奇怪了。
感谢Kan和mozilla大哥的热心帮助,顺便问一下,那里有gtk的图象处理编程的资料啊,网上少的可怜啊,两位可有好推荐的?感激不尽
回复

使用道具 举报

 楼主| 发表于 2005-8-10 03:49:23 | 显示全部楼层
一个奇怪的问题,还是忍不住再问一下
GdkDrawable *drawable;
GtkWidget *da;
da = gtk_drawing_area_new ();
drawable = da->window;
gdk_draw_rectangle (drawable,da->style->white_gc,TRUE,0,0,512,512);
应该没啥错吧,可运行的时候居然提示
gdk/gdkdraw.c: line 410 (gdk_draw_rectangle): assertion `GDK_IS_DRAWABLE (drawable)' failed
这里的drawable有什么问题吗?好象大家都这么用的啊?
回复

使用道具 举报

发表于 2005-8-10 08:20:31 | 显示全部楼层
己经在前面说过了,你要在屏幕上画图要用PIXMAP或BITMAP!不能向da->window里面画东西的。da->drawable 不是一个DRAWABLE!
回复

使用道具 举报

发表于 2005-8-10 08:24:17 | 显示全部楼层
下面的代码,通过PIXBUF显示一个test.jpeg,点击鼠标后,会在点击处面画一方块
#include <gtk/gtk.h>
    GtkWidget *window;
    GtkWidget *drawarea;
    GdkPixbuf *pixbuf;
    GdkPixmap *pixmap=NULL;
    gint width, height;

static void
draw_brush (GtkWidget *widget, gdouble x, gdouble y)
{
  GdkRectangle update_rect;

  update_rect.x = x - 5;
  update_rect.y = y - 5;
  update_rect.width = 10;
  update_rect.height = 10;
  gdk_draw_rectangle (pixmap,
                      widget->style->black_gc,
                      TRUE,
                      update_rect.x, update_rect.y,
                      update_rect.width, update_rect.height);
  gtk_widget_queue_draw_area  (widget, update_rect.x,update_rect.y,
                              update_rect.width,update_rect.height);
}

static gboolean configure_event (GtkWidget *widget,GdkEventConfigure *event,gpointer data)
{
        if (pixmap)
                g_object_unref (pixmap);
        pixmap = gdk_pixmap_new (widget->window,
                        widget->allocation.width,widget->allocation.height,-1);

        gdk_draw_rectangle (pixmap,widget->style->white_gc,TRUE,0, 0,
                      widget->allocation.width,widget->allocation.height);



        gdk_draw_pixbuf (pixmap,drawarea->style->white_gc,pixbuf,
                                        0,0,0,0,width,height,0,0,0);
  return TRUE;
}

static gboolean expose_event(GtkWidget *widget,GdkEventExpose *event,gpointer data)
{
        gdk_draw_drawable (widget->window,
                     widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
                     pixmap,
                     event->area.x, event->area.y,
                     event->area.x, event->area.y,
                     event->area.width, event->area.height);
  return TRUE;
}
static gint button_press_event(GtkWidget *widget,GdkEventButton *event,gpointer data)
{
  
  g_print("mouse press on %f, %f",event->x, event->y);
  draw_brush (widget, event->x, event->y);
  return TRUE;
}

void destroy( GtkWidget *widget,
              gpointer   data )
{
    gtk_main_quit ();
}

int main( int   argc,
          char *argv[] )
{
   

    gtk_init (&argc, &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   
    g_signal_connect (G_OBJECT (window), "delete_event",
                      G_CALLBACK (destroy), NULL);
    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (destroy), NULL);
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);

    pixbuf = gdk_pixbuf_new_from_file ("test.jpg",NULL);
    if (pixbuf == NULL) {
                        g_print ("Can't load image \n !!");
                }
       
    width = gdk_pixbuf_get_width (pixbuf);
    height = gdk_pixbuf_get_height (pixbuf);
    drawarea = gtk_drawing_area_new ();
    gtk_widget_set_size_request (drawarea,width,height);
   
    g_signal_connect (drawarea,"configure_event",
                        G_CALLBACK (configure_event), NULL);
   

    g_signal_connect (drawarea, "expose_event",
                        G_CALLBACK (expose_event), NULL);
                       
    gtk_widget_set_events (drawarea, GDK_EXPOSURE_MASK
                         | GDK_LEAVE_NOTIFY_MASK
                         | GDK_BUTTON_PRESS_MASK
                         | GDK_POINTER_MOTION_MASK
                         | GDK_POINTER_MOTION_HINT_MASK);
    gtk_signal_connect (GTK_OBJECT(drawarea), "button_press_event",
                      (GtkSignalFunc) button_press_event, NULL);                               
    gtk_container_add (GTK_CONTAINER (window), drawarea);
   
   
   
    gtk_widget_show_all (window);
   

    gtk_main ();
   
    return 0;
}
回复

使用道具 举报

发表于 2005-12-6 17:15:34 | 显示全部楼层
[quote:2ec641b477="xiaocong213"]pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 512, 512);
for(int i=0;i<512;i++)
{
for(int j=0;j<512;j++)
{
put_pixel (pixbuf, i, j,255,255,255);
}
}
就是用上面的方法发现pixbuf里的像素值还是0,我明明都设成255了啊,难道上面的那两个循环根本就没做?
可是我在回调函数时打开文件用了一模一样的循环,像素值是改变了,可是显示还是一片白。why?[/quote]

gtk_image_set_from_pixbuf(...)重新载入pixbuf
回复

使用道具 举报

发表于 2006-1-6 12:09:40 | 显示全部楼层
gtk-demo中的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-3 00:38 , Processed in 0.048251 second(s), 14 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表