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

Delphi Discussion :

Je n'arrive pas à transmettre une copie d'écran(TBitmap) à un TServerSocket


Sujet :

Delphi

  1. #1
    En attente de confirmation mail Avatar de Matt2094
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 295
    Points : 237
    Points
    237
    Par défaut Je n'arrive pas à transmettre une copie d'écran(TBitmap) à un TServerSocket
    Bonjour à tous,

    Je me heurte à un problème depuis quelques temps : je n'arrive pas à envoyer une copie d'écran depuis un TClientSocket, vers un TServerSocket. Je me suis aperçu que l'erreur ne venait ni de la copie d'écran (j'ai essayé le code de copie d'écran à part, et ça marche), ni de l'envoie (quand j'envoie un TBitmap qui n'est pas une copie d'écran, ça marche aussi).
    L'erreur doit donc venir de la récéption, mais je n'arrive pas à la résoudre ...

    Merci d'avance.


    P.S : J'utilise ce code pour la copie d'écran :
    Bitmap.Canvas.Handle := GetDC(0);

  2. #2
    Membre régulier
    Inscrit en
    Mai 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 69
    Points : 76
    Points
    76
    Par défaut
    pour faire une copie d'ecran, essaies ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    DC := GetDc(0);
    Bmp := TBitmap.Create;
    Bmp.PixelFormat := pf32bit;
    R := RECT(0,0,800,600); // enfin ce que tu veux copier...
    Bmp.Width := R.Right - R.Left + 1;
    Bmp.Height := R.Bottom - R.Top + 1;
     
    BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, DC, R.Left, R.Top, SRCCOPY);
    // ensuite envoie le Bmp à ton socket (je suppose via un stream) et detruit le Bmp.Free
    Bruno.

  3. #3
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    si tu veux envoyé une seul foi une copy de l'ecran voir:
    TBitmap.SaveToStream
    Enregistre le bitmap dans un flux.
    procedure SaveToStream(Stream: TStream); override;
    Description
    Utilisez SaveToStream pour écrire l'image bitmap dans le flux spécifié par le paramètre Stream. Par exemple, spécifiez un objet TBlobStream en paramètre Stream pour sauvegarder l'image bitmap dans un champ graphique d'un ensemble de données.
    mais des copy d'écran succésive en temp réel
    TBitmap.ScanLine
    Offre un accès indicé à chaque ligne de pixels.
    property ScanLine[Row: Integer]: Pointer;
    Description
    ScanLine n'est utilisée qu'avec les DIB (Device Independent Bitmaps) pour les outils d'édition d'images manipulant les pixels à un bas niveau.
    + de l'magination
    pour plus d'information sur scanligne: scanline/
    PAS DE DESTIN, C'EST CE QUE NOUS FAISONS

  4. #4
    En attente de confirmation mail Avatar de Matt2094
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 295
    Points : 237
    Points
    237
    Par défaut
    Merci Bruno et edam, mais le problème ne vient pas de la copie d'écran, mais plutôt de la récéption : une fois que j'ai reçu le TBitmap, si je ne fais rien avec et que je laisse moisir dans la procedure, ça roule, mais dès que je veux par exemple l'afficher dans un TImage, ou un peu le modifier, il y a une exception qui se déclenche qui dit : "Violation d'accès dans le module..."(vous connaissez la suite) ...

  5. #5
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Pourrais-tu préciser les data qui sont envoyés par le socket :
    - le stream de l'image?
    - le handle du canvas?
    - le Tbitmap (pointeur de 4 octets)?
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  6. #6
    En attente de confirmation mail Avatar de Matt2094
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 295
    Points : 237
    Points
    237
    Par défaut
    J'ai cherché à faire simple, et j'ai juste envoyer le TBitmap. J'ai utiliser ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ClientSocket1.Socket.SendBuf(Bitmap, sizeof(Bitmap));
    Et pour la récéption, ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Socket.ReceiveBuf(Bitmap2, Socket.ReceiveLength);

  7. #7
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Bitmap étant un objet, ce qui va être transmis est le pointeur de l'objet soit une size de 4. L'erreur access violation vient de ce que l'on ne peut pas utiliser dans le process 2 l'objet déclaré dans le process 1.

    Comme indiqué par Edam, il faut :
    • dans le process1 : "sérializer" le bitmap dans un buffer via un savetostream , transmettre le buffer
    • dans le process2 : créer un bitmap, récupérer l'image via un loadfromstream depuis le buffer reçu.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  8. #8
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    Citation Envoyé par Matt2094
    Et pour la récéption, ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Socket.ReceiveBuf(Bitmap2, Socket.ReceiveLength);
    tu crée ton objet bitmap2?
    tu l'a initialisé?? car il doit avoir la mem espace mémoir de bitmap1
    je te dis sa simplement pour répondre à:
    il y a une exception qui se déclenche qui dit : "Violation d'accès dans le module..."(vous connaissez la suite) ...
    pas pour l'utilisé ; fait comme ta dit Graffito
    pour scanligne c'est simplement pour ne pas bloqué votre poste pour envoyé tt une image en une seul fois
    PAS DE DESTIN, C'EST CE QUE NOUS FAISONS

  9. #9
    En attente de confirmation mail Avatar de Matt2094
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 295
    Points : 237
    Points
    237
    Par défaut
    Ok, merci Graffito ! Je penses que ça va marcher maintenant.
    Et merci aussi à Edam, pour la fonction scaneline.

  10. #10
    En attente de confirmation mail Avatar de Matt2094
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 295
    Points : 237
    Points
    237
    Par défaut
    Encore une erreur ...
    Quand je veux sauvegarder mon TBitmap dans un TStream, il y a une exception "erreur abstraite" qui se déclenche ... Pour initialiser le Stream, j'ai utilisé ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stream := TStream.Create;
    Et pour sauegarder le TBitmap, j'utilise ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Bitmap.SaveToStream(Stream);
    Je suppose que l'erreur doit être très bête, mais je ne l'ai pas trouvée ...

  11. #11
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Tstream est une classe "abstraite" dont les classes Stream utiles dérivent.
    Il faut utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var stream: TMemoryStream;
    stream := TMemoryStream.Create;
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  12. #12
    En attente de confirmation mail Avatar de Matt2094
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 295
    Points : 237
    Points
    237
    Par défaut
    Il y a encore une erreure ...

    Bon, voici le code côté client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    var
      S: TMemoryStream;
    begin
      S := TMemoryStream.Create;
      Image1.Picture.Bitmap.SaveToStream(S);
      ClientSocket1.Socket.SendBuf(S, Sizeof(S));
    end;
    De ce côté, ça va ...

    Et du côté serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    var
      S: TMemoryStream;
    begin
      S := TMemoryStream.Create;
      Socket.ReceiveBuf(S, Socket.ReceiveLength);
      Image1.Picture.Bitmap.LoadFromStream(S);
    end;
    Là, il y a une violation d'accès à l'adresse sur le chargement du Stream.


    P.S : il y a un bitmap, dans le TImage du client.

  13. #13
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Même erreur qu'au debut, il ne faut pas envoyer la stream (en fait son pointeur), mais un buffer (tableau de caractère) que l'on remplit par la methode Tmemorystream.ReadBuffer après avoir fait le Tbitmap.savetoStream

    En lecture, on crée le stream, on le remplit via la methode memorystream.WriteBuffer, puis on fait le Tbitmap.loadfromStream.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  14. #14
    En attente de confirmation mail Avatar de Matt2094
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 295
    Points : 237
    Points
    237
    Par défaut
    Excuse mon ignorence et mon manque de compréhension, mais est-ce-que tu peux me donner un ptit code exemple, du côté client ?

  15. #15
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Leprincipe de base est décrit dans le code ci-dessous.
    Pour de grandes images (Si la taille de l'image dépasse la longueur d'un échange socket), il faudra transmettre l'image en plusieurs sendbuf.

    Code send :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
      S: TMemoryStream;
      Buf : array of char ;
    begin
      S := TMemoryStream.Create;
      Buf.setlength(256000) ;
      Image1.Picture.Bitmap.SaveToStream(S);
      S.ReadBuffer(Buffer,S.size) ;
      ClientSocket1.Socket.SendBuf(Buffer,S.size);
    end;
    Code receive :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
      S: TMemoryStream;
      Buf : array of char ;
    begin
      S := TMemoryStream.Create;
      Buf.setlength(256000) ;
      Socket.ReceiveBuf(buffer,Socket.ReceiveLength);
      S.WriteBuffer(Buffer,Socket.ReceiveLength) ; 
      Image1.Picture.Bitmap.LoadFromStream(S);
    end;
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  16. #16
    En attente de confirmation mail Avatar de Matt2094
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 295
    Points : 237
    Points
    237
    Par défaut
    Encore une erreur : "Erreur de lecture du flux", dans la partie send, sur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    S.ReadBuffer(Buffer,S.size);

  17. #17
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Essaie (sans garantie) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    S.ReadBuffer(Buffer[0],S.size);
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

Discussions similaires

  1. [JNI] FindClass n'arrive pas à trouver une classe
    Par Benoit_Aligon dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 04/07/2006, 15h40
  2. Je n'arrive pas à recuperer une image
    Par lemonsoda dans le forum Langage
    Réponses: 6
    Dernier message: 26/01/2006, 09h32
  3. Réponses: 7
    Dernier message: 25/01/2006, 21h37
  4. [HTML][CSS] W3C--> Je n'arrive pas à résoudre une erreur
    Par gwendy dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 23/12/2005, 23h50
  5. Je n'arrive pas à détruire une fenêtre
    Par CORREGE Frédéric dans le forum MFC
    Réponses: 6
    Dernier message: 22/02/2004, 20h28

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