1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
| #include <gtk/gtk.h>
struct _SDraw
{
GtkWidget *drawing;
GdkPixbuf *Pixbuf_principal;
};
typedef struct _SDraw SDraw;
gboolean drawing_expose(GtkWidget *widget, GdkEventExpose *event, SDraw *pointeurs)
{
// on teste toujours si le pixbuf != NULL
if (!pointeurs->Pixbuf_principal)
{
g_print("Le pixbuf n'est pas valide. Pas d'affichage possible.\n");
return TRUE;
}
g_print("Le pixbuf est valide. Donc je peux l'afficher.\n");
// On affiche simplement le GdkPixbuf dans le GtkDrawingarea
gdk_draw_pixbuf(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
pointeurs->Pixbuf_principal, 0, 0, 0, 0,
gdk_pixbuf_get_width(pointeurs->Pixbuf_principal),
gdk_pixbuf_get_height(pointeurs->Pixbuf_principal),
GDK_RGB_DITHER_MAX, 0, 0);
return TRUE;
}
gboolean invert_pixbuf(SDraw *pointeurs)
{
gint i;
guchar *pixel=NULL;
GdkPixbuf *pixbuf_tmp=NULL;
// on teste toujours si le pixbuf != NULL
if (!pointeurs->Pixbuf_principal) return TRUE;
g_print("Le pixbuf est valide. Alors je peux inverser sa couleur.\n");
// On inverse tous les pixels (on passe du blanc au noir et inversement)
pixbuf_tmp=gdk_pixbuf_copy(pointeurs->Pixbuf_principal);
// On récupère le pointeur des pixels de l'image
pixel=gdk_pixbuf_get_pixels(pixbuf_tmp);
for (i=0; i < gdk_pixbuf_get_width(pixbuf_tmp)*gdk_pixbuf_get_height(pixbuf_tmp)*3; i++)
pixel[i]=pixel[i]^255;
// On recopie le nouveau pixbuf dans le pointeur principal
g_object_unref(pointeurs->Pixbuf_principal);
pointeurs->Pixbuf_principal=gdk_pixbuf_copy(pixbuf_tmp);
g_object_unref(pixbuf_tmp);
/*le fait de recopier le pixbuf, de traiter la copie pour finalement le
recopier de nouveau n'est là que pour l'exemple. Ce code est inutile au demeurant.*/
// Il faut maintenant demander la mise à jour du GtkDrawingArea.
drawing_expose(pointeurs->drawing, NULL, pointeurs);
return TRUE;
}
void drawing_realize(GtkWidget *widget, SDraw *pointeurs)
{
gint i=0;
guchar *pixel=NULL;
g_print("Cette fonction n'est appellée qu'une seule fois..\n");
// initialisation du pixbuf.
pointeurs->Pixbuf_principal=gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE,8,200,200);
// L'image est mise au noir.
// On récupère le pointeur des pixels de l'image
pixel=gdk_pixbuf_get_pixels(pointeurs->Pixbuf_principal);
for (i=0; i < gdk_pixbuf_get_width(pointeurs->Pixbuf_principal)*gdk_pixbuf_get_height(pointeurs->Pixbuf_principal)*3; i++)
pixel[i]=0;
// Mise en place de l'appel à la fonction de tracé toutes les secondes.
g_timeout_add_seconds(1, (GSourceFunc)invert_pixbuf, pointeurs);
}
void init_window(SDraw *pointeurs)
{
GtkWidget *fenetre_principale=NULL;
/* création de la fenêtre principale */
fenetre_principale=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(fenetre_principale), "test draw gdkpixbuf");
// Création d'une entrée texte
pointeurs->drawing=gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(fenetre_principale), pointeurs->drawing);
/* On connecte une fonction qui va initiliser le GtkDrawingarea ainsi que le pixbuf principal*/
g_signal_connect(G_OBJECT(pointeurs->drawing), "realize", (GCallback)drawing_realize, pointeurs);
/* On connecte aussi une fonction qui va s'occuper de l'affichage proprement dit du pixbuf.*/
g_signal_connect(G_OBJECT(pointeurs->drawing), "expose_event", (GCallback)drawing_expose, pointeurs);
// Affection des signaux pour fermeture de l'application
g_signal_connect(G_OBJECT(fenetre_principale), "destroy", (GCallback)gtk_main_quit, NULL);
// Affichage de la fenêtre
gtk_widget_show_all(fenetre_principale);
}
gint main(gint argc,gchar **argv)
{
SDraw *Pointeurs=g_malloc(sizeof(SDraw));
Pointeurs->drawing=NULL;
Pointeurs->Pixbuf_principal=NULL;
gtk_init(&argc, &argv);
init_window(Pointeurs);
gtk_main();
g_free(Pointeurs);
return 0;
} |