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

C++ Discussion :

Image jpeg : buffer -> file


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Par défaut Image jpeg : buffer -> file
    Bonjour,

    Voici mon problème :

    Je récupère dans un buffer une image jpeg à partir d'une caméra IP.
    Je connais donc la taille du buffer.

    Ensuite je copie l'image sur le disque avec fwrite.

    Sur linux, je peux visualiser l'image copiée ; cepedant sur windows ce n'est pas le cas. Lorsque je l'ouvre avec gimp par exemple j'ai le mesage suivant :
    "Corrupt JPEG data: premature end of data segment"

    Je me demande si le problème vient des différences entre linux et windows concernant les fins de ligne.

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    A propos des fin de ligne, il y a effectivement des diffférence entre linux et windows. LEs fichiers sont ils ouvert en mode texte ou binaire ?

    De plus, les images générées sur linux sont elles visualisables sur windows (et inversement) ?

  3. #3
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par mabu Voir le message
    A propos des fin de ligne, il y a effectivement des diffférence entre linux et windows.
    Oui mais cela ne concerne que les fichiers textes. Je ne pense pas qu'un fichier jpg entre dans cette actégorie

    Une autre possibilité est que le fichier jpg soit légèrement invalide/corrompu/non conforme, et que gimp sous linux sait le gérer alors que sous windows, il n'y arrive pas.

    Tu as essayé avec d'autre visualiseur d'e fichiers ?
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  4. #4
    Membre expérimenté
    Inscrit en
    Octobre 2007
    Messages
    285
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Octobre 2007
    Messages : 285
    Par défaut
    Bonjour,

    Quel est le format image du fichier ?
    Tout dépends des besoins, mais l'utilisation d'une librairie image fournissant des fonctions d'export vers les formats courants (Bitmap, jpeg, tiff, ...) ne vous faciliterait pas la vie ?

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Par défaut
    Tout d'abord je vous remercie pour votre aide.

    Les fichiers sont ouverts en mode binaire : fopen(file.c_str(), "wb")

    Les images créées sur linux sont également visualisables sur windows.

    Les images sont au format jpeg.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Par défaut
    Autre remarque :
    Les images crées sur windows ne sont pas visualisables sur linux.
    Donc je ne pense pas que gimp corrige le fichier.

    Le problème viendrait donc lors de l'écriture du fichier jpeg sur windows.


    J'ai trouvé une lib (FreeImage) qui permet d'enregistrer dans un fichier en bmp, à partir de mon buffer jpeg.
    Evidemment ça marche sur linux, mais pas sur windows.
    Mais dans ce cas, peut-être que le problème vient du fait que la dll est compilée avec MVSC alors que moi j'utilise le compilateur mingw. ( j'ai du pour cela modifier légèrement le fichier .h de la lib)

  7. #7
    Membre expérimenté
    Inscrit en
    Octobre 2007
    Messages
    285
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Octobre 2007
    Messages : 285
    Par défaut
    Citation Envoyé par sagopa Voir le message
    Les fichiers sont ouverts en mode binaire : fopen(file.c_str(), "wb")
    Il ne devrait pas avoir de problème dans ce cas entre windows et linux si mes souvenirs sont bon.

    Citation Envoyé par sagopa Voir le message
    Sur linux, je peux visualiser l'image copiée ; cepedant sur windows ce n'est pas le cas. Lorsque je l'ouvre avec gimp par exemple j'ai le mesage suivant :
    "Corrupt JPEG data: premature end of data segment"
    ... et ...
    Citation Envoyé par sagopa Voir le message
    Les images créées sur linux sont également visualisables sur windows.


    Citation Envoyé par sagopa Voir le message
    Les images sont au format jpeg.
    Est-ce que la fonction qui transforme le buffer en jpeg et OK ? Peut être que le standard n'est pas tout à fait respecté ? La caméra IP fournit peut être une image type "jpeg" (algo DCT, ....) mais il manque peut être des infos pour que linux puisse lire les données.
    Comment est transférer l'image de la caméra à votre logiciel ?

  8. #8
    Membre expérimenté
    Inscrit en
    Octobre 2007
    Messages
    285
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Octobre 2007
    Messages : 285
    Par défaut
    Citation Envoyé par sagopa Voir le message
    Autre remarque :
    Evidemment ça marche sur linux, mais pas sur windows.
    Mais dans ce cas, peut-être que le problème vient du fait que la dll est compilée avec MVSC alors que moi j'utilise le compilateur mingw. ( j'ai du pour cela modifier légèrement le fichier .h de la lib)
    Euh, effectivement, ce n'est pas franchement recommandé de croiser les compilateurs. En quoi avez vous modifié le fichier .h ?

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Par défaut
    J'ai l'impression que je me suis mal fait comprendre.

    Alors je récapitule.
    Les images crées sur linux sont visualisables sur linux et sur windows.
    Celles crées sur windows ne sont visualisables ni sur linux ni sur windows.

    Je n'ai pas de fonction pour transformer le buffer en jpeg. En faite, j'envoie une requête http à la caméra en utilisant les sockets (send). Cette caméra me renvoie alors une image jpeg avec une entete http (receive). Ensuite je sépare l'entete http et l'image jpeg.


    Concernant la lib FreeImage, j'ai du mettre en commentaires quelques redéfinitions :
    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
     
    typedef int32_t BOOL;
    typedef uint8_t BYTE;
    typedef uint16_t WORD;
    typedef uint32_t DWORD;
    typedef int32_t LONG;
     
    typedef struct tagRGBQUAD {
    #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
      BYTE rgbBlue;
      BYTE rgbGreen;
      BYTE rgbRed;
    #else
      BYTE rgbRed;
      BYTE rgbGreen;
      BYTE rgbBlue;
    #endif // FREEIMAGE_COLORORDER
      BYTE rgbReserved;
    } RGBQUAD;
     
    typedef struct tagRGBTRIPLE {
    #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
      BYTE rgbtBlue;
      BYTE rgbtGreen;
      BYTE rgbtRed;
    #else
      BYTE rgbtRed;
      BYTE rgbtGreen;
      BYTE rgbtBlue;
    #endif // FREEIMAGE_COLORORDER
    } RGBTRIPLE;
     
    typedef struct tagBITMAPINFOHEADER{
      DWORD biSize;
      LONG  biWidth; 
      LONG  biHeight; 
      WORD  biPlanes; 
      WORD  biBitCount;
      DWORD biCompression; 
      DWORD biSizeImage; 
      LONG  biXPelsPerMeter; 
      LONG  biYPelsPerMeter; 
      DWORD biClrUsed; 
      DWORD biClrImportant;
    } BITMAPINFOHEADER, *PBITMAPINFOHEADER; 
     
    typedef struct tagBITMAPINFO { 
      BITMAPINFOHEADER bmiHeader; 
      RGBQUAD          bmiColors[1];
    } BITMAPINFO, *PBITMAPINFO;
    Mais j'utilise cette lib pour la conversion jpeg -> bmp et écriture de l'image bmp sur le disque.
    Pour écrire l'image jpeg, j'utilise les fonctions fopen et fwrite

  10. #10
    Membre expérimenté
    Inscrit en
    Octobre 2007
    Messages
    285
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Octobre 2007
    Messages : 285
    Par défaut
    Citation Envoyé par sagopa Voir le message
    J'ai l'impression que je me suis mal fait comprendre.
    J'ai effectivement mal compris (Après lecture plus attentive, c'est un peu plus clair...).

    Très schématiquement, la caméra envoi une page du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <html>
    < des infos divers .../>
     
    <image>DU_CODE_BINAIRE_QUI_REPRESENTE_UN_FICHIER_JPEG</image>
     
    </html>
    Vous récupérer ce code que vous copier dans un fichier monfichier.jpg ?
    Si je me suis encore trompé,

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Par défaut
    Oui c'est à peu près ça.

    Je reçois par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    HTTP/1.0 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Expires: Thu, 01 Dec 1994 16:00:00 GMT
    Connection: close
    Content-Type: image/jpeg
    Content-Length: 50098
     
     
    DONNES DE L'IMAGE JPEG AVEC HEADER JPEG de taille 50098 bytes...
    Je reçois les données ci-dessus dans un buffer (uint8_t * dataRcv)

    Evidemment, avant d'écrire dans un fichier j'enlève la partie concernant le header http (grâce au 2 sauts de ligne), pour n'avoir que les données concernant l'image jpeg.

    j'ai donc un buffer qui ne contient que l'image (uint8_t * image)

  12. #12
    Membre expérimenté
    Inscrit en
    Octobre 2007
    Messages
    285
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Octobre 2007
    Messages : 285
    Par défaut
    La caméra fonctionnant surement sur un dérivé UNIX ou linux, n'y a t'il pas dans les données binaires du fichier html un retour à la ligne qui perturberai le bazard sous Windows ???

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Par défaut
    Après réception des données de la caméra j'ai écris ces données dans un fichier texte. J'ai une différence entre linux et windows.

    LINUX:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    HTTP/1.0 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Expires: Thu, 01 Dec 1994 16:00:00 GMT
    Connection: close
    Content-Type: multipart/x-mixed-replace; boundary=--myboundary
     
    --myboundary
    Content-Type: image/jpeg
    Content-Length: 50328
     
    ÿØÿà...
    WINDOWS:
    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
    HTTP/1.0 200 OK
     
    Cache-Control: no-cache
     
    Pragma: no-cache
     
    Expires: Thu, 01 Dec 1994 16:00:00 GMT
     
    Connection: close
     
    Content-Type: image/jpeg
     
    Content-Length: 50098
     
     
     
    ÿØÿà...

  14. #14
    Membre expérimenté
    Inscrit en
    Octobre 2007
    Messages
    285
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Octobre 2007
    Messages : 285
    Par défaut
    Je ne pense que la différence d'entête joue, par contre, si il y a une différence de structure dans les datas, là il peut avoir un problème.
    L'idéal serait une comparaison byte à byte des datas, mais pour cela, il faudrait la même image, et je ne pense pas que ce soit possible (? A moins de figer l'image stockée sur la caméra ?)

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Par défaut
    Oui tu as raison mais il n'est pas possible d'avoir la même image ...

  16. #16
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par sagopa Voir le message
    Oui tu as raison mais il n'est pas possible d'avoir la même image ...
    As tu acces à la caméra ?
    Est il possible de la sur-exposer, ou de jouer sur son gain pour avoir une image uniformement blanche ? (saturation)

    Si tu as deux images saturées, il est tout à fait concevable quelles soient identiques.

  17. #17
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Faut arrêter....
    Une requete HTTP est une requete HTTP... si c'est la même requête qui est envoyée au même serveur, c'est la même réponse qui est reçu (en tout cas dans le forme), le serveur étant incapable de detecter si cela vient de Windows ou de Linux ou d'un Sun-Spark ! Hors là ce n'est pas le cas....

    J'aimerai bien jeter un oeil au code de la query HTTP (en particulier les 'accept' qui sont passés) et du décryptage de la réponse.... (avec écriture dans le fichier texte)

    Juste histoire de voir plus clair dans cette partie...

    Pour le contenu de l'image JPEG... dans tous les cas c'est du binaire, et ca ne devrait poser aucun problême

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Par défaut
    Je ne sais pas s'il est possible d'avoir des images saturées ; je vais me renseigner.

    Voici la requete envoyée à la camera:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    GET /axis-cgi/jpg/image.cgi?resolution=640x480 HTTP/1.1
    Host: 172.23.7.28
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
    Maintenant je vais essayer de détailler un peu plus la séparation header http et données binaires de l'image:
    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
     
    //J'envoie la requete avec sa taille en octets
    Send(requete, taille requete);
    //Je recupère tout d'abord 1024 octets de la socket
    //1024 est choisi arbitrairement, mais suffisamment grand pour avoir le header http en entier
    Receive(dataRcv, 1024)
    //Recherche une occurence de "Content-Length: "
    uint8_t* content = (uint8_t *) strstr((char*) dataRcv, "Content-Length: ");
    //Recherche de la fin du header http
    uint8_t* endHeader = (uint8_t *) strstr((char*) content , "\r\n\r\n");
    *endHeader = 0x00;
    //Recupere la valeur de "Content-Length: ", cad la taille de l'image, dans imageSize
    sizeLength = STRLEN(content +16);
    length = (uint8_t *) MALLOC( sizeof(uint8_t) * sizeLength + 1 );
    memcpy(length, content+16, sizeLength);
    length[sizeLength] = 0;
    imageSize = atoi((char*) length);
    free(length);
    //Allocation memoire pour le buffer qui va contenir l'image
    uint8_t* downloadedImage = (uint8_t*) malloc( imageSize );
    //On Recupere la taille du header 
    sizeHeader = STRLEN(dataRcv) + 4;
    //Je copie la premiere partie de l'image, recuperée avec le header http, dans le buffer
    memcpy(downloadedImage, endHeader+4, 1024 - sizeHeader);
    //On definit la nouvelle taille (en octects tjs) à recevoir 
    sizeDataRcv = imageSize  - (PACKET_SIZE - sizeHeader);
    free(dataRcv);
    //On récupère la dernière partie de la réponse http qui correspond à la dernière partie de l'image
    Receive(dataRcv,sizeDataRcv );
    //Je copie la dernière partie dans le buffer
    memcpy(downloadedImage+(1024-sizeHeader), dataRcv, sizeDataRcv);
    free(dataRcv);
    //Enfin je copie l'image sur le disque pour vérifier si l'image a été récuperée correctement ou non
    FILE * bulk;
    if ( ( bulk = fopen("image.jpg", "wb") ) == NULL ) 
      cout << "Can't open file to write image.jpg" << endl;
    else
    {
      fwrite(downloadedImage, 1 , imageSize , bulk);
      fclose(bulk);
    }
    J'espère que c'est assez clair...
    Merci.

  19. #19
    Membre expérimenté
    Inscrit en
    Octobre 2007
    Messages
    285
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Octobre 2007
    Messages : 285
    Par défaut
    Citation Envoyé par nicroman Voir le message
    Faut arrêter....
    Une requete HTTP est une requete HTTP... si c'est la même requête qui est envoyée au même serveur, c'est la même réponse qui est reçu (en tout cas dans le forme), le serveur étant incapable de detecter si cela vient de Windows ou de Linux ou d'un Sun-Spark ! Hors là ce n'est pas le cas....
    Je suis partiellement d'accord, tout dépend le protocole caméra / PC qui pourrait varier suivant que coté PC, les fonctions sont du type WIN32 ou Linux

    Citation Envoyé par nicroman Voir le message
    J'aimerai bien jeter un oeil au code de la query HTTP (en particulier les 'accept' qui sont passés) et du décryptage de la réponse.... (avec écriture dans le fichier texte)

    Juste histoire de voir plus clair dans cette partie...
    Ca ferait avancer le problème...

    Citation Envoyé par nicroman Voir le message
    Pour le contenu de l'image JPEG... dans tous les cas c'est du binaire, et ca ne devrait poser aucun problême
    Oui le binaire, c'est le binaire. Mais comme dans le premier cas, la caméra pourrait se comporter différemment dans le formattage de ces données suivant les informations envoyée par le client.
    Deuxièmement, si dans le fichier HTML, il y des retour à la ligne ou autre (qui dépendent de l'os) cela peut expliquer le problème.
    Enfin, attention à la manière de lire le binaire (Big endian / little endian) ...

    Les raisons peuvent vraiment être variée.

    Je pense qu'une lecture attentive de la doc caméra devrait peut être aider (lire les petits * ou 1 2... en bas de page)


    Enfin pour l'idée d'une image blanche (ou noir d'ailleurs qui serait plus simple à obtenir), je ne suis pas sùr qu'on obtienne exactement le même code binaire du fichier JPEG, mais bon à essayer.

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 83
    Par défaut Problème résolu
    J'ai enfin trouvé le problème:

    En faite lorsque je faisais un receive pour lire les données de l'image de la socket, sur windows il n'est pas possible de lire tout l'image en entier, certainement du à une taille de buffer des sockets trop petite par rapport à la taille d'une image jpeg. Donc tant que je n'ai pas lu l'image en entier je fais de nouveau un receive pour avoir l'image en entier.

    Merci encore à tous.

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

Discussions similaires

  1. [SGBD] affichage d'image jpeg depuis une base mysql
    Par eric_300 dans le forum Requêtes
    Réponses: 2
    Dernier message: 10/09/2005, 12h27
  2. [DBase][BDE]Insérer des images JPeg dans un table.u
    Par migauvin dans le forum Bases de données
    Réponses: 3
    Dernier message: 24/08/2004, 12h03
  3. Compression d'une série d'images jpeg
    Par Tchello dans le forum Langage
    Réponses: 3
    Dernier message: 31/08/2003, 19h59
  4. Copier une image (jpeg) dans le presse papier
    Par benj63 dans le forum C++Builder
    Réponses: 2
    Dernier message: 29/07/2002, 14h51
  5. comment réduire une image jpeg (taille x*y)
    Par don-diego dans le forum C
    Réponses: 4
    Dernier message: 14/07/2002, 20h06

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