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+ avec C & C++ Discussion :

Lire une image à partir d'un tableau


Sujet :

GTK+ avec C & C++

  1. #1
    Membre confirmé Avatar de suzan_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 87
    Par défaut Lire une image à partir d'un tableau
    Bonjour, je bloque sur un truc un peu enervant... J'ai un tableau qui contient une adresse d'une image sur chaque ligne, quand je fais un printf pour voir son contenu tout est ok... mais quand je le passe à la fonction gtk_image_new_from_file, il affiche une croix rouge. gerror ne me renvoie rien comme si l'image s'était bien chargé. Et quand j'écris l'adresse directement dans ma fonction gtk_image_new_from_file, la évidemment il trouve l'image

    Voici le code :

    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
     
    GtkWidget *pImage;
    char tab_image[50][1000];
     
    fichier=fopen("image_list_complete.txt","r");
     
     
        if (fichier != NULL)
        {	
    		while (fgets(tab_image[var], 1000, fichier) != NULL) 
            {
    		printf("%s\n",tab_image[var]);
    		var=var+1;
    	} 
            fclose(fichier);
        }
    for(l=0;l<5;l++)
    {
            //ici tout s'affiche correctement
    	printf("%s\n",tab_image[l]);
    }
     
     pImage = gtk_image_new_from_file(tab_image[0]);
     
    if (pImage == NULL)
    {
       /* Affichage du message d'erreur standard : */
       printf ("%s\n", p_err->message);
       g_error_free (p_err);
    }
        gtk_box_pack_start(GTK_BOX(VBoxFrame_density), pImage, FALSE, FALSE, 5);

    J'ajoute que le fichier "image_list_complete.txt" contient des lignes d'adresses images comme celle ci : C:\\Users\\Suzan\\Documents\\Visual Studio 2008\\Projects\\CT Project\\Debug\\patients\\lady_gaga_10044\\1.JPG

    J'ai mis les doubles barres pour les espaces. J'ai essayé sans, ca ne marche pas non plus...
    Help

    Merci d'avance

  2. #2
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Portugal

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2009
    Messages : 27
    Par défaut
    Tu ne peux pas faire ça. Le prototype de la function gtk_image_new_from_file () a comme argument le type const char *filename. Tu doit passer le nom d'image qui se trouve dans le disque. La function qui charge le image c'est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    GdkPixbuf * gdk_pixbuf_new_from_file (const char *filename, GError **error)
    et se trouve ici.

  3. #3
    Membre confirmé Avatar de suzan_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 87
    Par défaut
    Merci pour ta réponse rapide et désolé pour ma réponse tardive

    Est- ce vraiment obligatoire de charger une image avec gdk_pixbuf_new_from_file?

    Sinon, j'ai vu qu'il fallait passer un pointeur sur cette adresse alors j'ai fais :

    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
    GtkWidget *pImage;
    char tab_image[50][1000];
     
    fichier=fopen("image_list_complete.txt","r");
     
     
        if (fichier != NULL)
        {	
    		while (fgets(tab_image[var], 1000, fichier) != NULL) 
            {
    		printf("%s\n",tab_image[var]);
    		var=var+1;
    	} 
            fclose(fichier);
        }
    for(l=0;l<5;l++)
    {
            //ici tout s'affiche correctement
    	printf("%s\n",tab_image[l]);
    }
     
    char* filename = NULL;	
     
    filename = (char*)malloc(sizeof(char));
    filename =  tab_image[0];
     
     pImage = gtk_image_new_from_file(filename);
     
     
        gtk_box_pack_start(GTK_BOX(VBoxFrame_density), pImage, FALSE, FALSE, 5);

    et la encore croix rouge

    Je ne me suis pas désespérée et j'ai essayé avec gdk_pixbuf_new_from_file comme tu avais dit :

    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
    GtkWidget *pImage;
     GdkPixbuf *pBuf = NULL;
    char tab_image[50][1000];
     
    fichier=fopen("image_list_complete.txt","r");
     
     
        if (fichier != NULL)
        {	
    		while (fgets(tab_image[var], 1000, fichier) != NULL) 
            {
    		printf("%s\n",tab_image[var]);
    		var=var+1;
    	} 
            fclose(fichier);
        }
    for(l=0;l<5;l++)
    {
            //ici tout s'affiche correctement
    	printf("%s\n",tab_image[l]);
    }
     
    char* filename = NULL;	
     
    filename = (char*)malloc(sizeof(char));
    filename =  tab_image[0];
     
     pImage = gtk_image_new_from_file(filename);
     
    pBuf = gdk_pixbuf_new_from_file(filename,&p_err);
        gtk_box_pack_start(GTK_BOX(VBoxFrame_density), pImage, FALSE, FALSE, 5);
     
    	if (pBuf == NULL)
    {
       /* Affichage du message d'erreur standard : */
       printf ("%s\n", p_err->message);
       g_error_free (p_err);
    }
     
    	pImage = gtk_image_new_from_pixbuf (pBuf);
    Et toujours rien : . Le message d'erreur est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Failed to open file :C:\\Users\\Suzan\\Documents\\Visual Studio 2008\\Projects\\CT Project\\Debug\\patients\\lady_gaga_10044\\1.JPG
    : invalid argument
    J'ai essayé avec et sans les doubles "\", rien ne change. Et quand je mets l'adresse directement la évidement ça marche...

    Help please

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Portugal

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2009
    Messages : 27
    Par défaut
    Je ne sais pas si tu as bien compris ou est mon français qui est mauvaise.
    Le prototype reçoit une variable du type const char *filename ("./img/img.png"). La function gdk_pixbuf_new_from_file () est responsable pour charger l'image et se trouve dans la function gtk_image_new_from_file. Si tu regarde la function gdk_pixbuf_new_from_file ici, tu peux voir que cette function fait le chargement de l'image avec l'appel g_fopen (). Allor, tu est obligeé de passer le chemin de l'image et pas le adresse. Je me trouve curieux, que-ce que tu veux faire?

    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
    GdkPixbuf * gdk_pixbuf_new_from_file (const char *filename, GError **error)
    {
     	        GdkPixbuf *pixbuf;
     	        int size;
     	        FILE *f;
     	        guchar buffer [128];
     	        GdkPixbufModule *image_module;
     	        gchar *display_name;
     	
     	        g_return_val_if_fail (filename != NULL, NULL);
     	        g_return_val_if_fail (error == NULL || *error == NULL, NULL);
     	       
     	        display_name = g_filename_display_name (filename);     
     	
     	        f = g_fopen (filename, "rb");
     	        if (!f) {
     	                g_set_error (error,
     	                             G_FILE_ERROR,
     	                             g_file_error_from_errno (errno),
     	                             _("Failed to open file '%s': %s"),
     	                             display_name,
     	                             g_strerror (errno));
     	                g_free (display_name);
    ...

  5. #5
    Membre confirmé Avatar de suzan_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 87
    Par défaut
    Oui, escuse il y a eu confusion, j'ai voulu dire le chemin dans ma dernière phrase.

    Quoiqu'il en soit, quand je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char* filename = NULL;	
     
    filename = (char*)malloc(sizeof(char));
    filename =  tab_image[0];
     pBuf = gdk_pixbuf_new_from_file(filename,&p_err);
    je passe bien à pBuf le contenu de filename, donc le chemin de mon image, non???

    Alors pourquoi ça ne marche pas?

  6. #6
    Membre confirmé Avatar de Gamall
    Profil pro
    Étudiant ENSEA
    Inscrit en
    Août 2009
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant ENSEA

    Informations forums :
    Inscription : Août 2009
    Messages : 252
    Par défaut
    Citation Envoyé par suzan_ Voir le message
    Oui, escuse il y a eu confusion, j'ai voulu dire le chemin dans ma dernière phrase.

    Quoiqu'il en soit, quand je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char* filename = NULL;	
     
    filename = (char*)malloc(sizeof(char));
    filename =  tab_image[0];
     pBuf = gdk_pixbuf_new_from_file(filename,&p_err);
    je passe bien à pBuf le contenu de filename, donc le chemin de mon image, non???

    Alors pourquoi ça ne marche pas?
    Ton code contient une fuite de mémoire car tu commence par allouer filename avec malloc(3), puis tu écrase sa valeur avec tab[0], le contenu alloué ne peut donc plus être libéré.
    Sinon, pour ton premier code, il y a quelque chose que je ne comprends pas, tu crée ton GtkImage, avec gtk_image_new_from_file, puis ensuite, tu déréférence p_err (un GError ?), aors qu'il n'a pas été initialisé lors du chargement du fichier. En effet, gtk_image_new_from_file ne prend pas de GError en paramètre, alors j'ai du mal à comprendre à quoi il sert et d'où il sort...


    Voici un exemple de code documenté de ce que tu semble vouloir faire, bonne lecture
    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
    #include <gtk/gtk.h>
     
    int
    main (int  argc,
          char *argv[])
    {
    	GtkWidget *window;
    	GtkWidget *box;
    	GtkWidget *image;
    	GdkPixbuf *pixbuf;
            /* Contiendra tout le contenu du fichier */
    	gchar *file_content;
            /* Contiendra chaque ligne du fichier */
    	gchar **files;
    	gchar **tmp;
    	GError *error;
     
     
    	gtk_init (&argc, &argv);
     
    	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    	g_signal_connect (G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
     
    	box = gtk_vbox_new (TRUE, 0);
    	gtk_container_add (GTK_CONTAINER(window), box);
     
    	/* On charge le contenu du fichier dans file_content.
    	 * D'après la doc, on doit libérer file_content, par 
    	 * la suite avec g_free
    	 */
    	g_file_get_contents ("image_list_complete.txt",
    			&file_content,
    			NULL,
    			&error);
    	if (NULL == file_content)
    	{
    		/* Si le fichier n'a pas pu être récuperé */
    		g_printerr ("%s", error->message);
    		g_free (error);
    		return -1;
    	}
     
    	/* On coupe la chaine file_content à chaque fois qu'on
    	 * rencontre un '\n'. Chaque chaine sera stockée dans 
    	 * files (tableau de chaine).
    	 * files doit être liberé avec g_strfreev
    	 */
    	files = g_strsplit (file_content, "\n", -1);
    	g_free (file_content);
     
    	/* On parcourt nôtre tableau qui contient maintenant les noms de fichiers.
    	 * l'avant dernière case est NULL, et l'avant dernière ne contient rien 
    	 * d'interessant. (une chaine vide)
    	 */
    	for (tmp = files; NULL != *(tmp+1); tmp++)
    	{
    		/* On charge les fichier un par un dans un pixbuf */
    		error = NULL;
    		pixbuf = gdk_pixbuf_new_from_file (*tmp, &error);
    		if (NULL == pixbuf)
    		{
    			/* Si le fichier n'a pas pu être chargé */
    			g_printerr ("%s", error->message);
                            g_error_free (error);
    		}
    		else
    		{
    			/* On crée le GtkImage à partir du pixbuf */
    			image = gtk_image_new_from_pixbuf (pixbuf);
    			gtk_container_add (GTK_CONTAINER(box), image);
    		}
    	}
     
    	/* On libère le tableau maintenant inutile */
    	g_strfreev (files);
     
    	gtk_widget_show_all (window);
     
    	gtk_main ();
     
     
    	return 0;
    }
    Résultat:

  7. #7
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Citation Envoyé par suzan_ Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    filename = (char*)malloc(sizeof(char));
    filename =  tab_image[0];
    Tu as un gros soucis de compréhension des pointeur là. En faisant cela, tu ne copies pas de données, ne fais que pointer vers une zone mémoire fraichement allouée, puis vers une autre. Au passage tu as perdu tout moyen de retrouver la zone allouée avec le malloc, c'est donc une fuite mémoire. Jette un coup d'oeil à cette vidéo pour comprendre un peu mieux comment fonctionnent les pointeurs: [ame="http://www.youtube.com/watch?v=6pmWojisM_E"]comment fonctionnent les pointeurs[/ame]

    Pour ton problème d'origine, j'ai trouvé la cause: la manière dont tu effectues la récupération des chemins de fichiers. Déjà tu n'as pas besoin de doubler les backslash '\' dans un fichier de données lu par ton programme. Tu n'as besoin de le faire que quand tu spécifies des noms en dur dans un fichier C, car le caractère backslash est un caractère d'échappement, et qu'en analysant le chemin "C:\nouveau dossier", le compilateur comprendrait le "\n" comme un retour chariot. Pour éviter cela, quand on veut indiquer que c'est bien le caractère backslash que l'on souhaite utiliser, on le double: "C:\\nouveau dossier".

    Autrement, pour ton problème initial, il vient du fait que tes chaînes de caractère contiennent encore le retour chariot en fin de ligne, et que le système cherche un fichier contenant ce retour chariot à la fin de son nom...

    Bon, ton exemple initial est clairement très imparfait, mais si tu souhaites le conserver, alors il te suffit après avoir lu chaque ligne de ton fichier, de les modifier pour enlever les éventuels espaces et retours chariots en fin de ligne avec g_strchomp.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    while (fgets(tab_image[var], 1000, fichier) != NULL)
    {
        g_strchomp (tab_image[var]);
        printf("%s\n",tab_image[var]);
        var=var+1;
    }

  8. #8
    Membre confirmé Avatar de suzan_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 87
    Par défaut
    Alors tout d'abord merci énormément à tous, je suis toujours étonnée de voir le niveau d'expertise des personnes sur ce site. Merci beaucoup d'avoir pris le temps de me répondre .

    Bon, ton exemple initial est clairement très imparfait, mais si tu souhaites le conserver, alors il te suffit après avoir lu chaque ligne de ton fichier, de les modifier pour enlever les éventuels espaces et retours chariots en fin de ligne avec g_strchomp.
    En effet ! cela marche nickel, je ne comprends pas exactement ce que cette fonction fais : elle enlève les espaces, mais alors comment le programme fais pour trouver le fichier ? Et elle enlève le retour chariot : tu parles du retour chariot qui se trouve à la fin d'une chaine de caractère? En quoi étais-ce un problème pour mon programme?

    Merci pour la vidéo, elle est très pédagogique ! Si j'ai bien compris je devrai faire un truc comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    *filename =NULL
    filename = (char*)malloc(sizeof(char));
    *filename =  tab_image[0];
    Sinon, pour ton premier code, il y a quelque chose que je ne comprends pas, tu crée ton GtkImage, avec gtk_image_new_from_file, puis ensuite, tu déréférence p_err (un GError ?), aors qu'il n'a pas été initialisé lors du chargement du fichier. En effet, gtk_image_new_from_file ne prend pas de GError en paramètre, alors j'ai du mal à comprendre à quoi il sert et d'où il sort...
    En effet c'était simplement une erreur de ma part, j'ai oublié de commenter la ligne du gtk_image_new_from_file


    artificier59 , je vais bien regarder ton code, car il a l'air clair et très propre et voir si ça marche pour moi, il a l'air bien mieux que le mien...Je pense jamais à mettre des conditions au cas ou ça ne marcherai pas.

    En tout cas je mets le sujet comme résolu car la solution de liberforce marche même si je dois rendre mon code plus propre.

    Merci encore à tous

  9. #9
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Citation Envoyé par suzan_ Voir le message
    cela marche nickel, je ne comprends pas exactement ce que cette fonction fais : elle enlève les espaces, mais alors comment le programme fais pour trouver le fichier ? Et elle enlève le retour chariot : tu parles du retour chariot qui se trouve à la fin d'une chaine de caractère? En quoi étais-ce un problème pour mon programme?
    La documentation de g_strchomp indique:
    Removes trailing whitespace from a string.
    C'est à dire que cette fonction retire tous les caractères d'espacement: espace ' ', tabulation '\t', retour chariot '\n', fin de ligne '\r' se trouvant à la fin de ta chaîne de caractères.

    Ainsi:
    " \t\ntoto va au marché \r\n"
    devient après le passage de g_strchomp:
    " \t\ntoto va au marché"

    Citation Envoyé par suzan_ Voir le message
    Et elle enlève le retour chariot : tu parles du retour chariot qui se trouve à la fin d'une chaine de caractère? En quoi étais-ce un problème pour mon programme?
    Tu lis les lignes contenues dans ton fichier texte une à une. Mais chaque ligne se finit par un retour chariot "\n".
    Tu penses avoir dans ta variable la chaîne suivante:
    "C:\\Users\\Suzan\\1.JPG"
    mais en fait, elle contient:
    "C:\\Users\\Suzan\\1.JPG\n"

    Et le retour chariot à la fin de la chaîne fait que le nom du fichier que tu essaies d'ouvrir ne correspond pas au nom réel, et le fichier n'est pas trouvé. Cela se voyait parce que tu faisais un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%s\n",tab_image[var]);
    et qu'il y avait une ligne vide entre chaque chemin affiché. Cela signifiait donc qu'il y avait deux retour chariot l'un après l'autre, et donc que ta chaine en contenait un. J'avais trouvé ça bizarre, mais je n'ai pas tilté tout de suite.

    Pour ce qui est de ta copie de chaines de caractères, tu n'as toujours pas compris comment cela fonctionne... Pour te consoler, en fait ici tu n'as aucun besoin d'utiliser malloc, parce que tu as déjà alloué un tableau de caractères sur la pile. Si tu veux te passer de tableau pré-alloué, alors oui, il te faudra utiliser malloc.

    Je ne te cache pas qu'effectivement, un tableau de caractères, c'est crade pour plein de raisons, notamment à cause du fait que si tu imposes une limite fixe à la taille d'un tableau, tu auras toujours des bugs dès que la taille sera devenue insuffisante. C'est pour ça qu'on utilise plutôt de l'allocation dynamique: on consomme juste ce dont on a besoin comme mémoire, et en plus pas besoin de recompiler le programme si on se rend compte qu'on a besoin de traiter des fichiers plus gros.

    Pour l'exemple, je vais tout de même commenter ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char *filename =NULL;
    filename = (char*)malloc(sizeof(char));
    *filename =  tab_image[0];
    Ligne 1: ok

    Ligne 2: sizeof(char) vaut 1, donc tu viens d'allouer 1 seul caractère... Et tu n'as donc pas assez de place pour stocker une chaîne. Si par exemple tu veux stocker 10 caractères, il te faut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    filename = malloc(10 * sizeof(char) + 1);
    En gros, pour 10 caractères, il t'en faut 11, parce qu'il y a toujours en plus le caractère de fin de chaîne '\0'. Bon, en fait tu devrais d'abord déterminer la longueur de la chaîne à copier avec strlen, puis effectuer un malloc de cette taille +1, pour être sûr d'avoir la longueur minimale requise. Tu peux aussi utiliser strdup (bibliothèque C standard) ou g_strdup (GLib) qui feront le même boulot d'un seul coup.

    Ligne 3: Bin là je sais même pas trop ce que ça fait, je ne pensais même pas que c'était autorisé. ça doit être équivalent à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *filename =  tab_image[0][0];
    En gros copies juste un caractère, au lieu de copier tous les caractères de la chaîne. Pour copier une chaîne de caractères, il te faut utilise strcpy (ou mieux, strncpy).

  10. #10
    Membre confirmé Avatar de suzan_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 87
    Par défaut
    Merci énormément j'apprends énormément comme ça.

    Alors bon je me suis inspiré de artificier59 avait fais et de ce que tu avais fais et j'en suis arrivé à ce code.

    Je resitue le contexte : j'ai tab_image qui est un tableau qui contient dans chacune des lignes l'adresse de mes images. (j'en suis sure!! ).

    Maintenant je veux afficher chacune de ces images dans une GTK_BOX. J'ai donc utilisé ce que tu m'a appris précédemment :
    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
     
    //je remplis mon pointeur tmp avec la première ligne du tableau, en faisant //bien attention au malloc ;)
    int size = strlen(tab_image[0]);
    	tmp=(char*)malloc(size * sizeof(char) + 1);
    	strcpy(tmp,tab_image[0]);
    // tant que ce pointeur ne pointera pas sur NULL	
    while (tmp !=NULL){
    		/* Je charge les fichier un par un dans un pixbuf */
     
    		error = NULL;
    		pixbuf = gdk_pixbuf_new_from_file (tmp, &error);
    		//je libere mon tmp
                    free(tmp);
                    if (NULL == pixbuf)
    		{
    			/* Si le fichier n'a pas pu être chargé */
    			g_printerr ("%s", error->message);
    		}
    		else
    		{
    			/* On crée le GtkImage à partir du pixbuf */
    			image = gtk_image_new_from_pixbuf (pixbuf);
    			 gtk_box_pack_start(GTK_BOX(VBoxFrame_density), image, FALSE, FALSE, 5);
    		}
    //je vais maintenant remplir mon pointeur avec la deuxième ligne du tableau 
    //toujours en faisant attention au malloc
    		va=va+1;
    		size =strlen(tab_image[va]);
    	tmp=(char*)malloc(size * sizeof(char) + 1);
    	strcpy(tmp,tab_image[0]);
     
     
     
    	}
    //un dernier free pour quand on sortira définitivement de la boucle 
    free(tmp);
    Evidemment ça ne marche pas

    En plus je suis à peu près sure que ça doit vous sembler affreux .
    Qu'est ce que j'ai fais de mal cette fois ??

    EDIT: je viens de me rendre compte que j'avais oublié les free... je viens de les rajouter.

  11. #11
    Membre confirmé Avatar de Gamall
    Profil pro
    Étudiant ENSEA
    Inscrit en
    Août 2009
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant ENSEA

    Informations forums :
    Inscription : Août 2009
    Messages : 252
    Par défaut
    Je passe en coup de vent, juste pour dire, j'ai oublié de libérer mon GError dans mon code du dessus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    		if (NULL == pixbuf)
    		{
    			/* Si le fichier n'a pas pu être chargé */
    			g_printerr ("%s", error->message);
                            g_error_free (error);
    		}
    		else
    		{
    			/* On crée le GtkImage à partir du pixbuf */
    			image = gtk_image_new_from_pixbuf (pixbuf);
    			gtk_container_add (GTK_CONTAINER(box), image);
    		}
    Bonne nuit

  12. #12
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Citation Envoyé par suzan_ Voir le message
    Maintenant je veux afficher chacune de ces images dans une GTK_BOX. J'ai donc utilisé ce que tu m'a appris précédemment :
    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
     
    //je remplis mon pointeur tmp avec la première ligne du tableau, en faisant //bien attention au malloc ;)
    int size = strlen(tab_image[0]);
    	tmp=(char*)malloc(size * sizeof(char) + 1);
    	strcpy(tmp,tab_image[0]);
    // tant que ce pointeur ne pointera pas sur NULL	
    while (tmp !=NULL){
    		/* Je charge les fichier un par un dans un pixbuf */
    		error = NULL;
    		pixbuf = gdk_pixbuf_new_from_file (tmp, &error);
    		if (NULL == pixbuf)
    		{
    			/* Si le fichier n'a pas pu être chargé */
    			g_printerr ("%s", error->message);
    		}
    		else
    		{
    			/* On crée le GtkImage à partir du pixbuf */
    			image = gtk_image_new_from_pixbuf (pixbuf);
    			 gtk_box_pack_start(GTK_BOX(VBoxFrame_density), image, FALSE, FALSE, 5);
    		}
    //je vais maintenant remplir mon pointeur avec la deuxième ligne du tableau 
    //toujours en faisant attention au malloc
    		va=va+1;
    		size =strlen(tab_image[va]);
    	tmp=(char*)malloc(size * sizeof(char) + 1);
    	strcpy(tmp,tab_image[0]);
     
    	}
    Evidemment ça ne marche pas

    En plus je suis à peu près sure que ça doit vous sembler affreux .
    Qu'est ce que j'ai fais de mal cette fois ??
    ça devient difficile et consommateur en temps de corriger ton code à chaque fois, parce que tu tapes des trucs au pif en disant à la fin "ça marche pas". Si ça ne marche pas, tu devrais être capable d'instrumenter ton code pour savoir pourquoi ça ne marche pas. Rajouter des traces, des tests... Tu crois qu'on fait comment ? Jette un coup d'oeil à g_debug pour tes traces, et g_assert pour vérifier les conditions dont tu es sûre, cela t'aidera à comprendre ce qui se passe avant de poster du code.

    Je te conseille aussi de nous soumettre du pseudo code, plutôt que directement du code. Ce sera plus simple de t'expliquer les problèmes. Qu'on comprenne si tu essaies de faire ce qu'il faut à la base, et que c'est la traduction en C qui te bloque, ou si c'est dans ta manière d'aborder le problème que ça coince.

    Pour t'aider à repérer des problèmes dans le code que tu nous as fourni, réponds à ces quelques questions:
    1. dans quel cas tmp vaut NULL ?
    2. peux tu nous expliquer à quoi sert malloc en général, et pourquoi tu l'utilises ici ?
    3. as tu besoin à tout moment des chemins vers toutes les images, ou uniquement d'une seule image (celle à charger), dont tu n'auras plus besoin du chemin vers le fichier ensuite ?

  13. #13
    Membre confirmé Avatar de suzan_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 87
    Par défaut
    Je suis désolée de t’embêter et je comprendrai si tu n'avais plus le temps de répondre. Mais je t'assures que je n'écris pas au pif et je n'ai pas tant l'habitude que ça de venir sur les forums, je me débrouille par moi même en général. Hier j'ai passé la journée à essayer de faire ça avant de poster.

    dans quel cas tmp vaut NULL ?
    tmp vaudra NULL quand il pointra sur une ligne du tableau tab_image qui ne contiendra rien.

    peux tu nous expliquer à quoi sert malloc en général, et pourquoi tu l'utilises ici ?
    Pour moi malloc sert à faire une demande d'allocation de mémoire, malloc renvoie donc un pointeur sur l'adresse qui a été réservé pour ma variable.
    Ici je dois avoir un pointeur qui parcourera chaque ligne de mon tableau.
    En incrémentant mon pointeur, j'avance d'une ligne sur ce qu'il pointe c'est à dire mon tableau.
    C'est pour cela que mes conditions sont sur le pointeur tmp. Dès qu'il pointe sur NULL, cela veut dire qu'il a parcouru chaque ligne de mon tableau contenant une adresse d'image. (pour moi c'était pas si stupide...)

    as tu besoin à tout moment des chemins vers toutes les images, ou uniquement d'une seule image (celle à charger), dont tu n'auras plus besoin du chemin vers le fichier ensuite ?
    Oui j'aurai besoin de ces images à tout moment. Pour expliquer le contexte, l'utilisateur choisira le dossier d'un client, qui deviendra le dossier courant. Ce dossier contenant des images, je cherche dans un premier temps à toutes les afficher, puis l'utilisateur choisira une image parmi toutes qui deviendra alors l'image courante sur laquelle il travaillera.
    Par la suite l'utilisateur pourra changer d'image courante, donc je pense avoir besoin des chemins vers toutes les images.

    Toute la partie traitement de l'image est déjà faite, j'y arrive mieux, c'est vraiment l'interface ou je débute.

    Encore une fois j'apprécie vraiment votre aide, et non, je ne me fiche pas de vous. Je bloque vraiment la dessus et j'essaie énormément de mon coté.

  14. #14
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Arf, désolé si j'ai utilisé un ton un peu péremptoire, je m'en suis suis rendu compte un peu sur le moment mais j'ai posté tout de même. Toutes mes excuses.

    En fait je ne doute absolument que tu bosses, mais il y a des fondamentaux que tu ne maîtrises pas. Et tu n'as pas encore appris à déterminer ce qui se passe, alors on doit faire le boulot du débogueur, ce qui n'est pas des plus gratifiants. Tu dois apprendre à analyser le comportement de ton programme, c'est la base pour trouver tes erreurs... Si tu ne sais pas ce qui se passe, tu ne peux pas savoir ce qui bloque ! Pour cela, 2 techniques:
    1. utiliser printf ou un équivalent comme g_debug pour afficher les valeurs des variables que tu souhaites examiner, et comprendre ce qui se passe (je préfère g_debug, comme cela ça les distingues des messages à afficher réellement à l'utilisateur)
    2. utiliser un débogueur, sans doute celui de Visual Studio dans ton cas (ou Code::Blocks), ou gdb si tu utilises le compilateur gcc, (ou un frontend, comme l'excellent Nemiver sous Linux)

  15. #15
    Membre confirmé Avatar de suzan_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 87
    Par défaut
    Arf, désolé si j'ai utilisé un ton un peu péremptoire, je m'en suis suis rendu compte un peu sur le moment mais j'ai posté tout de même. Toutes mes excuses.
    Il n'y a vraiment aucun problème, j'ai conscience que ça doit être super lourd pour vous.

    En fait je ne doute absolument que tu bosses, mais il y a des fondamentaux que tu ne maîtrises pas. Et tu n'as pas encore appris à déterminer ce qui se passe, alors on doit faire le boulot du débogueur, ce qui n'est pas des plus gratifiants.
    Encore une fois merci énormément, et c'est frustrant de ne pas pouvoir vous remercier plus pour tout le boulot que vous faites sur le forum.

    utiliser printf ou un équivalent comme g_debug pour afficher les valeurs des variables que tu souhaites examiner, et comprendre ce qui se passe (je préfère g_debug, comme cela ça les distingues des messages à afficher réellement à l'utilisateur)
    J'utilise des printf de partout , seulement je ne les mets pas quand je poste du code... Je vais essayer g_debug.

    utiliser un débogueur, sans doute celui de Visual Studio dans ton cas (ou Code::Blocks), ou gdb si tu utilises le compilateur gcc, (ou un frontend, comme l'excellent Nemiver sous Linux)
    Alors oui, j'ai toujours eu l'habitude d'utiliser le debogueur, seulement, ici j'ai au début de mon main des déclarations d'IplImage (d'OpenCV), et je ne sais pas pourquoi mais le debogueur de Visual Studio ne supporte pas ça, et s'arrête dès qu'il arrive à ces lignes.

    je regarde à fond dans le détail ce qui se passe et je reposte.
    merci encore

  16. #16
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Citation Envoyé par suzan_ Voir le message
    tmp vaudra NULL quand il pointra sur une ligne du tableau tab_image qui ne contiendra rien.
    C'est faux. Tu confonds le pointeur et la zone pointée. tmp n'est modifié qu'aux lignes 4 et 26, quand tu lui affectes l'adresse renvoyée par le malloc. malloc renvoie NULL, quand il n'y a plus de mémoire disponible, ou (il me semble) si tu lui demandes de t'allouer 0 octets. Donc le test à la ligne 7 n'échouera que quand tu auras épuisé toute ta mémoire -> C'est quasiment une boucle infinie.

    Citation Envoyé par suzan_ Voir le message
    Pour moi malloc sert à faire une demande d'allocation de mémoire, malloc renvoie donc un pointeur sur l'adresse qui a été réservé pour ma variable.
    C'est presque ça, mais tu as encore un peu de mal sur le vocabulaire. malloc renvoie une adresse. Un pointeur, c'est une variable de type "pointeur sur quelque chose", et qui contient une adresse. De plus, l'adresse en question n'a pas été "réservée" pour ta variable. Tu peux avoir différents pointeurs qui pointent vers la même adresse.

    Citation Envoyé par suzan_ Voir le message
    Ici je dois avoir un pointeur qui parcourera chaque ligne de mon tableau.
    En incrémentant mon pointeur, j'avance d'une ligne sur ce qu'il pointe c'est à dire mon tableau.

    C'est pour cela que mes conditions sont sur le pointeur tmp. Dès qu'il pointe sur NULL, cela veut dire qu'il a parcouru chaque ligne de mon tableau contenant une adresse d'image. (pour moi c'était pas si stupide...)
    Comme je l'ai dit plus haut, ce n'est pas ce que tu fais, tu confonds le pointeur et la zone mémoire pointée. A la rigueur, tu pourrais tester si ton pointeur pointe vers une chaîne vide:
    Mais même comme ça, tu n'auras jamais ce cas là si tu ne laisses pas la dernière ligne de ton fichier vide. Si la dernière ligne contient du texte, tu auras aussi une boucle infinie. Surtout que ligne 27 tu te trompes et copies toujours la première ligne, et pas la ligne suivant celle que tu viens d'examiner.

    Citation Envoyé par suzan_ Voir le message
    Oui j'aurai besoin de ces images à tout moment.
    Ce n'est pas ma question. Je parle des chemins vers les images (tes chaines de caractère), pas des images en elles-mêmes.

    Citation Envoyé par suzan_ Voir le message
    Pour expliquer le contexte, l'utilisateur choisira le dossier d'un client, qui deviendra le dossier courant. Ce dossier contenant des images, je cherche dans un premier temps à toutes les afficher, puis l'utilisateur choisira une image parmi toutes qui deviendra alors l'image courante sur laquelle il travaillera.
    Par la suite l'utilisateur pourra changer d'image courante, donc je pense avoir besoin des chemins vers toutes les images.
    Tout dépend si tu te bases sur les données déjà lues, ou si tu re-scannes le fichier contenant le chemin vers tes images (peut-être veux tu autoriser l'utilisateur à le modifier sans avoir à lancer ton logiciel ?).

  17. #17
    Membre confirmé Avatar de suzan_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 87
    Par défaut
    hallelujah !

    Je me disais bien quand même que parcourir mon tableau avec un pointeur c'était pas si stupide...
    Seulement tu avais raison c'était la condition sur le pointeur qui allait pas . Je regardais le pointeur et non ce qu'il pointait...(il faut mettre une étoile...)

    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
    //je remplis mon pointeur tmp avec la première ligne du tableau, en faisant //bien attention au malloc ;)
    int size = strlen(tab_image[0]);
    	tmp=(char*)malloc(size * sizeof(char) + 1);
    	strcpy(tmp,tab_image[0]);
    // tant que ce pointeur ne pointera pas sur une ligne vide	
    while (*tmp != '\0'){
    		/* Je charge les fichier un par un dans un pixbuf */
     
    		error = NULL;
    		pixbuf = gdk_pixbuf_new_from_file (tmp, &error);
    		//je libere mon tmp
                    free(tmp);
                    if (NULL == pixbuf)
    		{
    			/* Si le fichier n'a pas pu être chargé */
    			g_printerr ("%s", error->message);
    		}
    		else
    		{
    			/* On crée le GtkImage à partir du pixbuf */
    			image = gtk_image_new_from_pixbuf (pixbuf);
    			 gtk_box_pack_start(GTK_BOX(VBoxFrame_density), image, FALSE, FALSE, 5);
    		}
    //je vais maintenant remplir mon pointeur avec la deuxième ligne du tableau 
    //toujours en faisant attention au malloc
    		va=va+1;
    		size =strlen(tab_image[va]);
    	tmp=(char*)malloc(size * sizeof(char) + 1);
    	strcpy(tmp,tab_image[va]);
     
     
     
    	}
    //un dernier free pour quand on sortira définitivement de la boucle 
    free(tmp);
    Sutout que ligne 27 tu te trombes et copies toujours la première ligne, et pas la ligne suivant celle que tu viens d'examiner.
    petite erreur de recopie sur le site... désolée.

    Bon ça fais ce que je voulais, mais j'ai du rajouter une ligne vide dans mon fichier texte, il n'y a vraiment pas un moyen de dire : (attention sans faute ) Quand le contenu de mon pointeur est vide, je sors de ma boucle while.

    Un truc comme : while(*tmp !=NULL)

    Ne me dites rien!! Je vais chercher de moi même.

    Mille merci pour vos explications et votre patience.

  18. #18
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Ouais, enfin c'est loin d'être fini, hein, parce que la blague, c'est que si tu fais toujours ta lecture ligne à ligne comme avant dans un tableau 2 dimensions, tu n'as absolument pas besoin de malloc (surtout que là tu as des fuites mémoire). Ah, autre chose, dans les options d'édition de ton éditeur de texte, il doit y avoir quelques chose pour indenter ton code automatiquement. Utilise la, parce que du code mal indenté est plus difficile à lire.

  19. #19
    Membre confirmé Avatar de Gamall
    Profil pro
    Étudiant ENSEA
    Inscrit en
    Août 2009
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant ENSEA

    Informations forums :
    Inscription : Août 2009
    Messages : 252
    Par défaut
    Un truc comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    while(*tmp !=NULL)
    Attention, si dans mon code, j'ai parcouru le tableau jusqu'à NULL, il y avait une raison, la doc de g_strsplit dit qu'elle retourne un "newly-allocated NULL-terminated array of strings." Donc, je sais qu'en le parcrourant, je tomberais sur un pointeur NULL. Toi dans ton cas, tu n'utilise pas cette fonction, et tu ne sais pas quelle est la dernière valeur de ton tableau, tu ne peux donc pas mettre une telle condition dans ta boucle.
    En revanche, si tu connais le nombre de ligne de ton fichier, ou le nombre de case de ton tableau, tu peux le parcourir avec un compteur et une boucle for


    [EDIT] J'ai confondu ton tmp et ton tableau de chaine, en même temps, une chaine terminée par NULL

  20. #20
    Membre confirmé Avatar de suzan_
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 87
    Par défaut
    Ouais, enfin c'est loin d'être fini
    éh oui !! .

    Mais bon pour l'instant je vais lire bien attentivement les cours GTK. J'ai jamais eu de cours d'informatique, j'ai tout appris sur les tutoriels... ça à l'avantage d'être très ludique mais je pense pas que l'on aille toujours dans le coeur du problème.

    surtout que là tu as des fuites mémoire
    Ah bon?? Je libère mon pointeur après chaque utilisation, comment je peux en avoir? Comment le voir autrement que si ça bug?

    si tu fais toujours ta lecture ligne à ligne comme avant dans un tableau 2 dimensions, tu n'as absolument pas besoin de malloc
    En même temps mon tableau j'ai besoin d'un pointeur pour le parcourir, (surtout que gdk_pixbuf_new_from_file prend comme 1er argument un pointeur de type char). Et si je stocke les lignes de mon tableau dans un pointeur, il faut que je sois sure d'avoir la place d'ou l'intéret du malloc.

    Je suis sure qu'on peut faire sans, mais dans l'immédiat, le sujet de ce post est résolu et je ne veux plus vous embéter plus longtemps, vous avez déja été assez patient!

    Merci encore, je vous tiendrai au courant.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Lire une image TIF dans un tableau 2D
    Par getstar dans le forum Débuter
    Réponses: 2
    Dernier message: 03/04/2011, 14h44
  2. Afficher une image à partir d'un tableau de byte
    Par Fr3nchK1ss dans le forum JavaFX
    Réponses: 15
    Dernier message: 02/11/2009, 01h37
  3. Afficher une image à partir d'un tableau
    Par cadavor dans le forum C++
    Réponses: 6
    Dernier message: 23/05/2008, 13h25
  4. Afficher une image à partir d'un tableau de char
    Par Beavis dans le forum Débuter
    Réponses: 7
    Dernier message: 12/02/2008, 16h01
  5. créer une image à partir d'un tableau de pixels
    Par pfo69 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 03/12/2007, 06h46

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