QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1716|回复: 6

gtk如何将一个图片处理成drawable.

[复制链接]
发表于 2005-8-29 15:08:40 | 显示全部楼层 |阅读模式
也就是说,比如我有一个窗口A已经显示了一副图片a,现在我在gtkpixbuf中存了令一副图片b,现在我想用gdk_draw_pixbuf来将gtkpixbuf里面的b图片一部分去覆盖当前窗口A的图片中指定的部分.

前提:A的图片是用gtk_image_new_from_file ()直接引进的.

问题:如何将A窗口的图片转换为可编辑的图片,即(drawable,能被绘图)?

请高人帮忙,谢谢!
发表于 2005-8-29 16:44:54 | 显示全部楼层
楼主,你的A图片是怎么显示的?我想是应该是先gdk_draw_pixbuf到一个pixmap,再把pixmap显示在drawarea中的吧。
用gdk_draw_pixbuf函数,把A图片的GTKPIXBUF的地址改成GTKPIXBUF B的就可以了,再改一下显示区域的参数就可以了,仔细看看gdk_draw_pixbuf的参数。!
回复

使用道具 举报

发表于 2005-8-30 07:54:17 | 显示全部楼层
1)
如果你有了个GtkImage, 你可以用gtk_image_get_pixbuf 得到GdkPixbuf.

或者

另一种方法, 用gdk_pixbuf_new_from_file()读图像文件,得到GdkPixbuf,
然后用 gtk_image_new_from_pixbuf()得到GtkImage用于显示.
2)

然后,从GdkPixbuf 得到pixel 数组
guchar*     gdk_pixbuf_get_pixels(const GdkPixbuf *pixbuf);

3)
你可以直接修改pixel 数组的内容,改变图像。
回复

使用道具 举报

 楼主| 发表于 2005-8-30 09:30:57 | 显示全部楼层
另一种方法, 用gdk_pixbuf_new_from_file()读图像文件,得到GdkPixbuf,
然后用 gtk_image_new_from_pixbuf()得到GtkImage用于显示.

是直接用gdk_pixbuf_new_from_file()直接生成图像的.因为我用的是glade工具.下面是自动生成的代码:
[code:1]
GtkWidget*
create_pixmap                          (GtkWidget       *widget,
                                        const gchar     *filename)
{
  gchar *pathname = NULL;
  GtkWidget *pixmap;

  if (!filename || !filename[0])
      return gtk_image_new ();

  pathname = find_pixmap_file (filename);

  if (!pathname)
    {
      g_warning (_("Couldn't find pixmap file: %s"), filename);
      return gtk_image_new ();
    }

  pixmap = gtk_image_new_from_file (pathname);
  g_free (pathname);
  return pixmap;
}

GdkPixbuf*
create_pixbuf                          (const gchar     *filename)
{
  gchar *pathname = NULL;
  GdkPixbuf *pixbuf;
  GError *error = NULL;

  if (!filename || !filename[0])
      return NULL;

  pathname = find_pixmap_file (filename);

  if (!pathname)
    {
      g_warning (_("Couldn't find pixmap file: %s"), filename);
      return NULL;
    }

  pixbuf = gdk_pixbuf_new_from_file (pathname, &error);
  if (!pixbuf)
    {
      fprintf (stderr, "Failed to load pixbuf file: %s: %s\n",
               pathname, error->message);
      g_error_free (error);
    }
  g_free (pathname);
  return pixbuf;
}


/* This is used to set ATK action descriptions. */

void
glade_set_atk_action_description       (AtkAction       *action,
                                        const gchar     *action_name,
                                        const gchar     *description)
{
  gint n_actions, i;

  n_actions = atk_action_get_n_actions (action);
  for (i = 0; i < n_actions; i++)
    {
      if (!strcmp (atk_action_get_name (action, i), action_name))
        atk_action_set_description (action, i, description);
    }
}
[/code:1]
现在图像不能编辑.你说的数组方法,有没有例子?能不能帮忙想想办法!谢谢!
回复

使用道具 举报

发表于 2005-8-30 09:45:20 | 显示全部楼层
pixbuf能操作透明什么的,不能画东西 的,你要改用pixmap来操作,就是第一个函数返回的pixmap来操作
回复

使用道具 举报

发表于 2005-8-30 09:49:49 | 显示全部楼层
#include <gtk/gtk.h>
    GtkWidget *window;
    GtkWidget *drawarea;
    GdkPixbuf *pixbuf;
    GdkPixmap *pixmap=NULL;
    gint width, height;
     GdkPixbuf *pixbuf1;
    gint width1, height1;
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);
    gdk_draw_pixbuf (pixmap,drawarea->style->white_gc,pixbuf1,
                                        0,0,0,0,width1,height1,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)
{
  //if (event->button == 1 && pixmap != NULL)
      g_print("mouse press on %f, %f",event->x, event->y);
  draw_brush (widget, event->x, event->y);


  return TRUE;

}
static gint  motion_notify_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
g_printf("mouse move on %f,%f\n", 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 ("background.png",NULL);
    if (pixbuf == NULL) {
                        g_print ("Can't load image \n !!");
                }
       
    width = gdk_pixbuf_get_width (pixbuf);
    height = gdk_pixbuf_get_height (pixbuf);
   
    pixbuf1 = gdk_pixbuf_new_from_file ("button_off.png",NULL);
    if (pixbuf1 == NULL) {
                        g_print ("Can't load image \n !!");
                }
       
    width1 = gdk_pixbuf_get_width (pixbuf1);
    height1 = gdk_pixbuf_get_height (pixbuf1);
   
    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_signal_connect (GTK_OBJECT(drawarea), "motion_notify_event",
                      (GtkSignalFunc)  motion_notify_event, NULL);                                             
    gtk_container_add (GTK_CONTAINER (window), drawarea);
   
   
   
    gtk_widget_show_all (window);
   

    gtk_main ();
   
    return 0;
}

这段代码会载入一个图片,你在上面点鼠标会画一个方形上去的
回复

使用道具 举报

发表于 2005-8-30 15:57:42 | 显示全部楼层
[quote="xue_hu2001"]
现在图像不能编辑.你说的数组方法,有没有例子?


http://cybernetics.freewebspace.com/gtk/improc/node1.html
回复

使用道具 举报

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

本版积分规则

GMT+8, 2024-11-5 11:55 , Processed in 0.061398 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

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