IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ Discussion :

Pixbuf - Cairo - Calques


Sujet :

GTK+

  1. #1
    Membre régulier
    Homme Profil pro
    Lycéen
    Inscrit en
    Mars 2014
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mars 2014
    Messages : 76
    Points : 72
    Points
    72
    Par défaut Pixbuf - Cairo - Calques
    Bonjour,

    je souhaiterai savoir s'il serait possible de créer calques lorsque je dessine avec cairo ?

    A l'aide de Pixbuf je charge une image (une carte), et avec cairo je place des points dessus. Mon problème est que je souhaiterai avoir plusieurs types de points (sur des calques différents), ainsi que pouvoir choisir quels calques afficher.

    Je ne vois pas trop comment faire, je découvre cette bibliothèque.

    En vous remerciant par avance,

    Cordialement
    Reverse_

    PS : voici ma fonction de dessin

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    void cb_image_annotate(GtkImageViewer *imgv, GdkPixbuf *pixbuf, gint shift_x, gint shift_y, gdouble scale_x, gdouble scale_y, gpointer user_data)
    {
        int img_width = gdk_pixbuf_get_width(pixbuf);
        int img_height = gdk_pixbuf_get_height(pixbuf);
     
        cairo_surface_t *surface = cairo_image_surface_create_for_data(gdk_pixbuf_get_pixels(pixbuf), CAIRO_FORMAT_RGB24, img_width, img_height, gdk_pixbuf_get_rowstride(pixbuf));
        cairo_t *cr = cairo_create (surface);
        cairo_translate(cr, -shift_x, -shift_y);
        cairo_scale(cr, scale_x, scale_y);
     
        cairo_set_source_rgba (cr, 0,0,1.0,0.6);
        cairo_set_line_width(cr, 3);
     
        struct node_point *p_node = header.first;
     
        while(p_node)
        {
     
            cairo_arc(cr, p_node->current.x, p_node->current.y, 12, 0.0, 2*G_PI);
            cairo_stroke(cr);
     
            p_node = p_node->next;
        }
     
        cairo_surface_destroy(surface);
        cairo_destroy(cr);
     
        (void)imgv;
        (void)user_data;
    }

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Bonjour.

    Voila un bel exercice .

    Je n'ai jamais essayé mais de prime à bord je pencherai pour l'utilisation de cairo_surface_t*, une par calque. Chaque surface est créée avec cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    cairo_surface_t *   cairo_surface_create_similar        (cairo_surface_t *other,
                                                             cairo_content_t content,
                                                             int width,
                                                             int height);
    • other serait la surface de fond (ton pixbuf),
    • content indiquerait une surface transparente : CAIRO_CONTENT_ALPHA CAIRO_CONTENT_COLOR_ALPHA
    • width et height la taille de l'image de fond.


    Lorsque l'utilisateur choisit un calque, tu sélectionnes en interne la surface correspondante et tu crées un cairo_t* en fonction de cette surface avec la fonction suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cairo_t *           cairo_create                        (cairo_surface_t *target);
    Il est important de noter que je n'ai rien essayer de tout cela. C'est l'idée que je m'en fait.

  3. #3
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Ta problématique a titillée ma curiosité . Je me suis à mon clavier pour tenter de mettre en application ce que je viens d'expliquer.

    Voila le code source d'un exemple qui crée un fond noir avec un texte blanc. ensuite quatre calques (des cairo_surface_t*) sont créés et insérés dans une liste chaînée.

    Le principe de la liste permet par exemple de choisir lequel des calques doit être dessus un autre. L'ordre des calques dans la liste influe donc directement sur le niveau des calques.

    Chaque calque est transparent par défaut. Un texte est ajouté avec une couleur variant légèrement l'un par rapport à l'autre. Les texte se chevauchent. Ca montre bien l'effet des calques.

    Une copie d'écran :
    Nom : Capture d'écran - 18012017 - 20:45:39.png
Affichages : 273
Taille : 11,0 Ko

    Le code source qui va avec (il manque la libération mémoire avant de quitter mais pour l'exemple ca n'apporte rien de plus):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include <gtk/gtk.h>
     
    typedef struct
    {
      GtkBuilder *builder;
      GList *calclist;
    } SGlobalData;
     
    typedef struct
    {
      cairo_surface_t *surface;
      GdkRGBA color;
    } SCalc;
     
     
    gboolean
    on_drawingarea_draw (GtkWidget *widget, cairo_t *cr, SGlobalData *gui)
    {
      gint width, height;
      static gboolean firstaccess = TRUE; // Permet de configurer les calques à la première exécution de cette fonction
     
      // Récupération de la taille de la surface de fond
      gtk_widget_get_size_request (widget, &width, &height);
     
      // Affichage de l'image de fond (fond noir avec texte en blanc "image de fond")
      cairo_paint (cr);
      cairo_set_source_rgb (cr, 1, 1, 1);
      cairo_move_to (cr, 0, 15);
      cairo_set_font_size (cr, 20);
      cairo_show_text (cr, "Image de fond");
     
      // Création si besoin des différents calques
      if (firstaccess)
        {
          gint i, j=25;
          gchar *text=NULL;
          cairo_t *newcr = NULL;
          SCalc *calc = NULL;
     
          for (i=0; i<4; i++)
    	{
    	  // Déclaration d'un nouveau calque
    	  calc = g_new (SCalc, 1);
     
    	  calc->surface = cairo_surface_create_similar (cairo_get_target (cr), CAIRO_CONTENT_COLOR_ALPHA, width, height);
    	  calc->color.red = i*0.2;
    	  calc->color.green = 1;
    	  calc->color.blue = i*0.3;
    	  calc->color.alpha = 1;
     
    	  // Création d'un nouveau context en fonction de la nouvelle surface
    	  newcr = cairo_create (calc->surface);
     
    	  // Ecriture en blanc dans la nouvelle surface "calque n°x"
    	  cairo_set_source_rgb (newcr, calc->color.red, calc->color.green, calc->color.blue);
    	  cairo_move_to (newcr, j-15, j);
    	  text = g_strdup_printf ("calque n°%d", i+1);
    	  cairo_set_font_size (newcr, 20);
    	  cairo_show_text (newcr, text);
    	  g_free (text);
     
    	  // Ajout du nouveau calque à la fin de la liste
    	  gui->calclist = g_list_append (gui->calclist, calc);
     
    	  // Suppression du context devenu inutile
    	  cairo_destroy (newcr);
    	  j+=10;
    	}
     
          firstaccess = FALSE;
        }
     
      // Affichage de tous les claques
      GList *list = gui->calclist;
      while (list)
        {
          cairo_set_source_surface (cr, ((SCalc*)(list->data))->surface, 0, 0);
          cairo_paint (cr);
          list = g_list_next(list);
        }
     
      return FALSE;
    }
     
    gint
    main (gint argc, gchar *argv[])
    {
      SGlobalData gui;
      GtkWidget *window=NULL;
      GtkWidget *drawingarea = NULL;
     
      gui.calclist = NULL;
     
      gtk_init (&argc, &argv);
     
      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      drawingarea = gtk_drawing_area_new ();
      gtk_widget_set_size_request (drawingarea, 200, 200);
      gtk_container_add (GTK_CONTAINER (window), drawingarea);
     
      g_signal_connect (G_OBJECT (window), "destroy", (GCallback) gtk_main_quit, NULL);
      g_signal_connect (G_OBJECT (drawingarea), "draw", (GCallback) on_drawingarea_draw, &gui);
     
      gtk_widget_show_all (window);
     
      gtk_main ();
     
      return 0;
    }

  4. #4
    Membre régulier
    Homme Profil pro
    Lycéen
    Inscrit en
    Mars 2014
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mars 2014
    Messages : 76
    Points : 72
    Points
    72
    Par défaut
    Bonsoir,

    premièrement désolé de ne pas avoir pu répondre plutôt..

    Sinon merci beaucoup c'est exactement ce que je souhaitais faire, je vais pouvoir un peu plus comprendre le fonctionnement de Cairo !

    Merci beaucoup !
    Cordialement,
    Reverse_

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [CAIRO] - Calques pour le dessin
    Par Eyeofhorus dans le forum GTK+ avec C & C++
    Réponses: 9
    Dernier message: 21/08/2007, 00h04
  2. deplacer scrollbar dans calque
    Par prodi_64 dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 21/12/2004, 12h18
  3. [FLASH MX2004] Mettre un calque invisible ?
    Par Ticoche dans le forum Flash
    Réponses: 6
    Dernier message: 19/11/2004, 15h23
  4. Réponses: 4
    Dernier message: 02/11/2004, 20h11
  5. [Flash MX] Probleme de calques
    Par yonat94 dans le forum Flash
    Réponses: 2
    Dernier message: 28/04/2004, 12h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo