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++Builder Discussion :

afficher les images d'une caméra via http sous bcb c++6


Sujet :

C++Builder

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2011
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2011
    Messages : 19
    Par défaut afficher les images d'une caméra via http sous bcb c++6
    Bonjour à tous,

    Je suis actuellement en train de faire un programme dans le cadre de ma formation et je suis incapable de résoudre un problème de récupération des images via une caméra ip.

    J'utilise un "client socket" afin d'envoyer les trames HTTP correspondant aux screenshot et dans l'evènement OnRead du socket je traite la récupération du fichier (image).

    Néanmoins, lorsque je fais cela en boucle (afin de récupérer les images continuellement et séquentiellement), l'image que je reçois est parfois complétement abimée et déformée. Je rafraichi l'image avec un timer...

    Je ne sais absolument pas pourquoi ça me fait cela, si vous avez une solution svp aidez moi.

    Voici quelques bout de codes correspondant à ce que j'ai fait:

    J'active le timer toutes les N ms:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
      Soc->Active = true;
    }
    Dans le "OnWrite" du Socket:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void __fastcall TForm1::SocWrite(TObject *Sender, TCustomWinSocket *Socket)
    {
            Soc->Socket->SendText("GET /cgi-bin/video.jpg?size=2 HTTP/1.0 \r\n\r\n");
    }
    Dans le "OnRead":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void __fastcall TForm1::SocRead(TObject *Sender, TCustomWinSocket *Socket)
    {
            char buffer[102000]; // buffer de recuperation des paquets venant du serveur
     
            int nbLu = Socket->ReceiveBuf(buffer, 102000 );  // lire les paquets
            pStream->Write(buffer, nbLu);       // transferer dans le stream
                                                  // pour traitement ulterieur
    }
    Dans le "OnDisconnect":
    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
     
    void __fastcall TForm1::SocDisconnect(TObject *Sender,
          TCustomWinSocket *Socket)
    {
        i = 0, j = 0;
        int comp;
        unsigned char var[4], var2[4]="ÿØÿÀ", tab;      // À ou þ
     
        pStream->Position = 0;    // pos = 0
        while(pStream->Read(var,4)){
            i+=4;
            comp = strncmp(var,var2,4);
            if(comp == 0) break;
        }
        i-=4;
        pStream->Position = i;
        pStream->Read(var,4);
        pStream->Position = 0;
        while(pStream->Read(&tab,2)){
            j+=2;
            if(!strncmp(&tab,"ÿ",2)){
              pStream->Read(&tab,2);
              j+=2;
              if(!strncmp(&tab,"Ù",1)){
                break;                  //si on a FFD9 on quitte
              }
            }
        }
        tailleImage = j - i;
     
        DisplayImage();   //traite et affiche l'image
        CleanUp();
        btConnect->Caption = "Connecter";
    }
    Et enfin voici la fonction "DisplayImage()":
    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
     
    void __fastcall TForm1::DisplayImage()
    {
      unsigned char buf[40000] = "";
     
      try
      {
        pFluxImage->Position = 0;
        pStream->Position = i;  // debut code jpeg après le Header dans le stream
        pStream->Read(buf, tailleImage);
        pFluxImage->Write(buf, tailleImage);
        pFluxImage->Position = 0;
        jp->LoadFromStream(pFluxImage);     // charger le jpeg converti en bitmap
     
        Image1->Picture->Assign(jp); // afficher l'image
     
      }
      catch (...)
      {
        MessageBeep(0);
      }
     
      pFluxImage->Position = 0;
    }
    Ces instructions sont effectuées séquentiellement. Si vous trouvez une erreur ou quelque chose qui pourrai m'aider à résoudre mon problème svp n'hésitez pas, je suis très à la bourre pour mon projet de fin d'années.

    J'attends vos messages ! merci

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 051
    Par défaut
    Tu pouvais poursuivre ton premier sujet Récupérer une image avec un socket?

    C'est même surprenant que tu puisses recevoir quelque chose de cohérent !
    Si je comprend le code tu parcours les données reçues (HTTP) jusqu'au début d'un fichier Image (JPEG), à partir de là tu utilises les données !

    Dans le OnRead, c'est bien, tu accumule les packets successifs, à mon avis, tu n'obtiens jamais un buffer de 102000 mais plutot 8192 au mieux

    Ta caméra fonctionne certe en IP (TCP\IP) mais là clairement tu l'utilises via un protocol de niveau supérieur le HTTP !

    Utilise un TIdHTTP, tu récupéreras le stream HTTP déjà prêt à l'emploi !
    Je te l'ai déjà dit !

    Je n'ai pas d'exemple à te donner dans le programme que je maintiens, les Camera AXIS (accessible via HTTP) sont fournis avec un ActiveX AxisMediaControl qui fait tout ce boulot, n'ayant pas encore fait moi même ce type de développement (je l'ai fait ClientSocket à ServerSocket, mais jamais ClientSocket à server HTTP embarqué), je ne peux pas t'aider plus que la théorie
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2011
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2011
    Messages : 19
    Par défaut
    Bonjour,
    effectivement j'hésitais à continuer sur mon sujet précédent mais étant donné que j'ai marqué "résolu" j'ai préféré faire un autre sujet..

    En fait je reçois l'image correctement approximativement 8 fois sur 10 . Mais des fois je reçois un peu n'importe quoi.
    Par contre pour le buffer tout dépend des caméras je pense étant donnée que je reçois les données sous forme de paquet pouvant aller jusqu'à plus de 30 000 !
    J'ai mis 102 000 c'est effectivement un peu excessif mais vaut mieux être large que pas assez non?

    Le TidHttp j'ai essayé je m'y pencher un peu mais je n'étais pas très à l'aise dessus.

    A vrai dire si je pouvais recevoir toujours les bonnes images j'aurai fini cette partie de mon projet (puisque j'ai fais le reste de mon projet qui consiste à faire une détection de mouvement).

    Avec le TidHttp comment on envoie une requête? Comment on reçois le flux contenant l'image?

    Merci encore pour ta présence et ton aide !

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 051
    Par défaut
    Tu as une méthode Get dans le TIdHTTP qui renvoie une chaine
    Tu as la chance d'avoir BCB6 qui fourni une excellente aide dont celle sur TIdHTTP

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    procedure Get(AURL: string; const AResponseContent: TStream); overload;
    function Get(AURL: string): string; overload;
    Get is an overloaded method used to retrieve the file or data for the resource specified in AURL.

    AURL is the complete, fully-qualified location of the resource.

    AResponseContent is the TStream that is the destination for data retrieved using the specified URL .

    Use Get(AUrl) to retrieve the data from AURL and return the contents as the String result of the function.

    Use Get(AUrl, AResponseContent) to retrieve data from the URL and write the return values to the TStream specified by AResponseContent.

    Get relies on the DoRequest method to perform the HTTP transfer.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2011
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2011
    Messages : 19
    Par défaut
    Merci j'ai essayé ce que tu m'as donné et ça fonctionne !
    Par contre en mettant les instructions dans un timer afin de rafraichir l'image, mon application est lente (lorsque je déplace ma fenêtre par exemple ça lag) .

    Est-ce qu'il y a un moyen plus optimisé?

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2011
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2011
    Messages : 19
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
      unsigned char buf[30000];
      pStream->Position = 0;
      IdHTTP1->Get("http://192.168.2.5/cgi-bin/video.jpg?size=2", pStream);
      int pos = pStream->Position;
      pStream->Position = 0;
      pStream->Read(buf, pos);
      pFluxImage->Write(buf, pos);
      pFluxImage->Position = 0;
      jp->LoadFromStream(pFluxImage);
      Image1->Picture->Assign(jp); // afficher l'image
      pFluxImage->Position = 0;
    C'est ce qu'il y a dans mon timer ...

  7. #7
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 051
    Par défaut
    C'est logique tout le temps d'attente HTTP et les copies de mémoire sont dans le Timer, plus tu lance souvent plus ton programme semblera lent !

    tu devrais mettre dans un Thread
    Ajoute une Section Critique autour du LoadFromStream et du Picture->Assign (ce dernier reste dans le TTimer)

    Cela devrait améliorer les traitements !
    Le top serait de supprimer le Timer et d'emettre un message interne via PostThreadMessage du thread vers le main demander un Invalidate, et c'est dans le OnPaint que tu fait le Picture->Assign
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. Réponses: 2
    Dernier message: 19/04/2014, 15h46
  2. Afficher les image dans une Gridview
    Par nitch01 dans le forum ASP.NET
    Réponses: 2
    Dernier message: 30/06/2011, 08h11
  3. afficher les images dans un email via outlook est possible
    Par kaayna dans le forum Webmarketing
    Réponses: 4
    Dernier message: 23/02/2010, 21h17
  4. Rediriger les images d'une caméra vidéo
    Par GDMINFO dans le forum Débuter
    Réponses: 1
    Dernier message: 08/11/2009, 18h22
  5. [JSP]Afficher les images d'une ArrayList ?
    Par Bobsinglar dans le forum Struts 2
    Réponses: 7
    Dernier message: 08/04/2008, 18h18

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