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

Langage Delphi Discussion :

[Rio 10.3.3] Transférer une image en REST


Sujet :

Langage Delphi

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 89
    Points : 102
    Points
    102
    Par défaut [Rio 10.3.3] Transférer une image en REST
    Bonjour,

    Je recherche un exemple de code partie cliente et partie serveur.

    L'idée est qu'une application Cliente en REST (Android, IOS et Windows) puisse aller chercher sur un serveur REST une image.
    Je sais très bien le faire avec une String, mais pas avec un TTimage.

    Est-ce que qqu'un aurait un bout de code exemple ?

    Cordialement

    Carmichael

  2. #2
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 735
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 735
    Points : 5 405
    Points
    5 405
    Par défaut
    Tout dépend de ce que renvoie l'api.
    Ce qui est certains, c'es qu'elle ne te renvoie pas un TImage.

    La plupart des API renvoie soit un fichier soit un flux.

  3. #3
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    664
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Deux Sèvres (Poitou Charente)

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 664
    Points : 3 648
    Points
    3 648
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    Je vous invite à regarder mon petit projet DelphiFunCurisosity disponible sur mon GitHub.
    C'était dans le cadre d'une compétition organisée par Embarcadero où il fallait utiliser les API REST de la NASA. Mon projet utilise donc les API mise à disposition par la NASA pour récupérer des images du rover Curiosity (sur Mars).
    On sélectionne la caméra que l'on souhaite et la date de la prise de vue.

  4. #4
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 504
    Points : 2 776
    Points
    2 776
    Billets dans le blog
    10
    Par défaut
    Voici un exemple l'image est sérialisé dans le ficher A.TXT puis désérialisée depuis ce fichier.
    Le fichier A.TXT similaire à un format DFM est en ASCII

    Nom : nouveau-3.png
Affichages : 496
Taille : 33,7 Ko

    Dans ton cas une partie sur le serveur, une partie sur le client.

    Ne pas oublier (Un)RegisterClasses([TTreeComponent, TImage]);
    Fichiers attachés Fichiers attachés

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 89
    Points : 102
    Points
    102
    Par défaut
    Bonjour,

    Merci aux personnes qui m'ont apporté leur aide.
    Je vous fais un retour par rapport à ce que j'ai pu tirer de vos aides respectives.

    Coté serveur :
    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
    function TServerMethods1.RecupImage( fic : String) : TJSONArray;
    var
      chemin_fic : String;
      flux : TFileStream;
      retour : TJSONArray;
     
    begin
      //Initialisation
      retour := TJSONArray.Create;
     
      //Si le fichier existe, on fabrique un FileStream, et on le convertit en JSONArray.
      if (FileExists(chemin_fic)) then
         begin
         MonLogNominatif.Ecrire('I', 'On envoie ce fichier qui existe : ' + chemin_fic);
         flux := TFileStream.Create(chemin_fic, fmOpenRead);
         retour := TDBXJSONTools.StreamToJSON(flux, 0, flux.Size);
         end
      else begin
           flux := TFileStream.Create('C:\RepImages' + PathDelim + 'Default.png', fmOpenRead);
           end;
      flux.Free;
      Result := retour;
    end;
    Si j'essaie le code du serveur sous Chrome, j'obtiens bien un Json de l'image sous la forme :
    {"result":[[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,4,87,0,0,3,145,8,6,0,0,0,55,72,77,218,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,14,196,0,0,14,196,1,149,43,14,27,0,0,0,7,116,73,77,69,7,225,5,9,12,6,55,67,217,89,144,0,0,32,0,73,68,65,84,120,218,236,189,123,152,94,85,121,247,255,89,107,239,253,236,231,60,207,156,114,78,8,33,4,76,128,138,19,64,4,116,80,68,131,193,42,117,242,179,85,16,197,6,133...

    Coté Client, je n'ai pas encore réussi à faire une implémentation correcte, car le code suivant ne fonctionne pas.

    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
    var
      fic : String;
      mon_json_array : TJSONArray;
      mon_stream : TStream;
     
    begin
      fic := 'MonPaysage.png';
     
      //On récupère le JSONArray depuis le serveur nommé Serveur.
      mon_json_array := TJSONArray.Create(Serveur.RecupImage(fic));
     
      //On décode le JSONArray en stream
      mon_stream := TStream.Create;
      mon_stream.Position := 0;
      mon_stream := TDBXJSONTools.JSONToStream(mon_json_array);
      //On charge le flux dans l'image.
      Image1.Bitmap.LoadFromStream(mon_stream);
     
    end;
    Ce code à la mauvaise idée de me retourner "TStream.Seek non implémenté."
    Cela provient du fait qu'il ne faut pas instancier TStream.
    Bon d'accord.
    Mais alors, si j'utilise TMemoryStream j'ai une erreur => Type incompatible TMEmoryStream et TStream.

    Une idée ?


    Cordialement

    Carmichael

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 875
    Points : 11 365
    Points
    11 365
    Billets dans le blog
    6
    Par défaut
    Bonsoir,
    Le code fonctionne-t-il comme ceci ?

    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
    var
      fic : String;
      mon_json_array : TJSONArray;
      mon_stream : TMemoryStream;
     
    begin
      fic := 'MonPaysage.png';
     
      //On récupère le JSONArray depuis le serveur nommé Serveur.
      mon_json_array := TJSONArray.Create(Serveur.RecupImage(fic));
     
      //On décode le JSONArray en stream
      mon_stream := TMemoryStream.Create;
     
      mon_stream := TDBXJSONTools.JSONToStream(mon_json_array);
     
      //On charge le flux dans l'image.
      mon_stream.Position := 0;
      Image1.Bitmap.LoadFromStream(mon_stream);
    A défaut, où se situe l'erreur "Types incompatibles TMEmoryStream et TStream" ? Dans l'appel à JSONToStream ? Dans le LoadFromStream ?

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 89
    Points : 102
    Points
    102
    Par défaut
    Bonsoir,

    Non, ce code ne se compile pas (ni en Win64, ni en Win32) lorsque mon_stream est déclaré comme TMemoryStream
    Il tombe en erreur sur la ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mon_stream := TDBXJSONTools.JSONToStream(mon_json_array);
    [dcc64 Erreur] FenPrincipale.pas(1041): E2010 Types incompatibles : 'TMemoryStream' et 'TStream'

    J'ai déplacé l'instruction : mon_stream.Position := 0;comme vous l'avez suggéré. Ce qui fait que le nouveau code est :

    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
    var
      fic : String;
      mon_json_array : TJSONArray;
      mon_stream : TMemoryStream;
     
    begin
      fic := 'MonPaysage.png';
     
      //On récupère le JSONArray depuis le serveur nommé Serveur.
      mon_json_array := TJSONArray.Create(Serveur.RecupImage(fic));
     
      //On décode le JSONArray en file stream
      mon_stream := TMemoryStream.Create;
      mon_stream := TDBXJSONTools.JSONToStream(mon_json_array);
     
      //On charge le flux dans l'image.
      mon_stream.Position := 0;
      ImageFond.Bitmap.LoadFromStream(mon_stream);
     
    end;

    Bien sur, l'erreur est toujours présente :
    [dcc64 Erreur] FenPrincipale.pas(1041): E2010 Types incompatibles : 'TMemoryStream' et 'TStream'

    Cordialement

    Carmichael

  8. #8
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 875
    Points : 11 365
    Points
    11 365
    Billets dans le blog
    6
    Par défaut
    Juste un petit déplacement de le ligne qui affecte le flux au retour :
    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
    function TServerMethods1.RecupImage( fic : String) : TJSONArray;
    var
      chemin_fic : String;
      flux : TFileStream;
      retour : TJSONArray;
     
    begin
      //Initialisation
      retour := TJSONArray.Create;
     
      //Si le fichier existe, on fabrique un FileStream, et on le convertit en JSONArray.
      if (FileExists(chemin_fic)) then
      begin
         MonLogNominatif.Ecrire('I', 'On envoie ce fichier qui existe : ' + chemin_fic);
         flux := TFileStream.Create(chemin_fic, fmOpenRead);
     
      end
      else begin
           flux := TFileStream.Create('C:\RepImages' + PathDelim + 'Default.png', fmOpenRead);
      end;
     
      retour := TDBXJSONTools.StreamToJSON(flux, 0, flux.Size);
     
      flux.Free;
      Result := retour;
    end;
    Pour la récupération, il ne faut certainement pas créer le flux, puisqu'il est fourni par la fonction de décodage du JSON : l'appel à TStream.Seek (dû à l'affectation de sa position à 0) plantait après un TStream.Create puisque c'est une méthode non implémentée sauf dans ses descendants, notamment celui probablement renvoyé par le JSON ToStream :
    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
    var
      fic : String;
      mon_json_array : TJSONArray;
      mon_stream : TStream;
     
    begin
      fic := 'MonPaysage.png';
     
      //On récupère le JSONArray depuis le serveur nommé Serveur.
      mon_json_array := TJSONArray.Create(Serveur.RecupImage(fic));
     
      //On décode le JSONArray en stream
      mon_stream := TDBXJSONTools.JSONToStream(mon_json_array);
     
      //On charge le flux dans l'image.
      mon_stream.Position := 0;
      Image1.Bitmap.LoadFromStream(mon_stream);

  9. #9
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 504
    Points : 2 776
    Points
    2 776
    Billets dans le blog
    10
    Par défaut
    Est ce que tu as regardé l'exemple que je t'ai envoyé ?

  10. #10
    Membre éprouvé
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Points : 1 073
    Points
    1 073
    Par défaut
    Bonjour,

    pour que le retour soit affichable il faut modifier légèrement 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
    var
      fic: string;
      mon_json_array: TJSONArray;
      mon_stream: TStream;
    begin
      fic := 'C:\Users\Cirec\Pictures\brick015.bmp';
     
      // On récupère le JSONArray depuis le serveur nommé Serveur.
      mon_json_array := TJSONArray.Create(RecupImage(fic));
      if Assigned(mon_json_array) then
        try
          if mon_json_array.Items[0] is TJSONArray then
             // si présence d'un array of array alors on prend le premier.
            mon_stream := TDBXJSONTools.JSONToStream(mon_json_array.Items[0] as TJSONArray)
          else
            mon_stream := TDBXJSONTools.JSONToStream(mon_json_array);
          if Assigned(mon_stream) then
            try
              mon_stream.Position := 0;
              // On charge le flux dans l'image.
              Image1.Picture.Bitmap.LoadFromStream(mon_stream);
            finally
              mon_stream.Free;
            end;
        finally
          mon_json_array.Free;
        end;
    end;
    TJSONArray.Create renvoi un tableau de tableaux (dans ce cas un seul)
    la version JSON le montre bien, l'objet commence avec 2 crochets '"result":[['


    Citation Envoyé par ALWEBER
    Est ce que tu as regardé l'exemple que je t'ai envoyé ?
    moi j'ai regardé et c'est bien vu
    je garde sous le coude
    ce que j'aime moins c'est le fait de devoir recenser les objets ... mais bon.



    cordialement,

    @+

  11. #11
    Membre émérite
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 504
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 504
    Points : 2 776
    Points
    2 776
    Billets dans le blog
    10
    Par défaut
    Suite à l'exemple présenté voici la version client/serveur d'images en pièce jointe
    Nom : Annotation 2020-01-14 191902.png
Affichages : 417
Taille : 64,0 Ko
    Fichiers attachés Fichiers attachés

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 89
    Points : 102
    Points
    102
    Par défaut
    Bonjour,

    Merci à tous les contributeurs.

    Spécialement pour Alweber : Oui, j'ai regardé votre exemple. Et même si cela ne se voit pas dans mon code, votre exemple fut ma première source d'inspiration. Ensuite, j'ai consulté pas mal la documentation en ligne. Avec plus ou moins de succès
    Pour ce qui est du choix d'utiliser du JSON plutot qu'une sérialisation standard comme celle que vous proposer, cela provient du fait que le JSON est à la mode depuis quelques années, et que les outils sont très nombreux dans le RAD studio, mais aussi à l'extérieur.

    Au passage, je suggère à Embarcadero de publier des exemples de code récents, car beaucoup de fonction sont inutilisables avec la seule lecture de la doc.


    Grace aux différentes contribution, voici le code définitif :


    Coté serveur :

    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
    function TServerMethods1.RecupImage(fic : String) : TJSONArray;
    var
      flux : TFileStream;
      retour : TJSONArray;
      chemin_fic : String;
    begin
      //Initialisation
      retour := TJSONArray.Create;
      chemin_fic := 'C:\MonDossierImages' + PathDelim + fic;
     
      //Corps
      if (FileExists(chemin_fic)) then
         begin
         flux := TFileStream.Create(chemin_fic, fmOpenRead);
         end
      else begin
           flux := TFileStream.Create'C:\MonDossierImages'+ PathDelim + 'Default.png', fmOpenRead);
           end;
      retour := TDBXJSONTools.StreamToJSON(flux, 0, flux.Size);
     
      //On s'en va.
      flux.Free;
      Result := retour;
    end;

    Coté Client :

    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
    procedure TForm1.ClicBouton(Sender: TObject);
    var
      fic : String;
      mon_json_array : TJSONArray;
      mon_stream : TStream;
     
    begin
      fic := 'MonPaysage.png';
     
      //On récupère le JSONArray depuis le serveur nommé Serveur.
      mon_json_array := TJSONArray.Create(Serveur.RecupImage(fic));
     
      //On décode le JSONArray en file stream
      mon_stream := TDBXJSONTools.JSONToStream(mon_json_array.Items[0] as TJSONArray);
     
      //On charge le flux dans l'image.
      mon_stream.Position := 0;
      Image1.Bitmap.LoadFromStream(mon_stream);
     
      mon_stream.Free;
      mon_json_array.Free;
    end;

    Bien sur, maintenant, il faut rendre ce code robuste avec des tests, c'est ce que suggère Sirec avec sa contribution.

    Lors de mes tentatives j'avais essayé, ce code (coté client) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mon_stream := TDBXJSONTools.JSONToStream(mon_json_array.Items[0]);
    Dans les faits, je ne comprends toujours pas pourquoi il faut spécifier : "as TJSONArray" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mon_stream := TDBXJSONTools.JSONToStream(mon_json_array.Items[0] as TJSONArray);
    C'est quelque chose de mystérieux. Enfin pour moi.
    Merci à tous.
    Je vais maintenant essayer de construire l'opération inverse : un upload depuis le client vers le serveur.
    Je ne sais pas si c'est possible.

    Cordialement

    Carmichael

  13. #13
    Membre éprouvé
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Points : 1 073
    Points
    1 073
    Par défaut
    re,

    je viens de comprendre pourquoi on avait un "array of array" à la place d'un simple tableau
    ce qu'on s'attend à avoir ici !!

    le coupable c'est cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      //On récupère le JSONArray depuis le serveur nommé Serveur.
      mon_json_array := TJSONArray.Create(Serveur.RecupImage(fic));
    RecupImage renvoi déjà un TJSONArray
    il faut remplacer par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      //On récupère le JSONArray depuis le serveur nommé Serveur.
      mon_json_array := Serveur.RecupImage(fic);
    et du coup plus besoin de caster

    tu peux directement faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            mon_stream := TDBXJSONTools.JSONToStream(mon_json_array);
    Cordialement,

    @+

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 89
    Points : 102
    Points
    102
    Par défaut
    Bonjour,

    C'est effectivement le cas.


    Cordialement

    Carmichael

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

Discussions similaires

  1. Transférer une image sur un serveur FTP
    Par Evodub dans le forum API standards et tierces
    Réponses: 31
    Dernier message: 09/07/2019, 14h55
  2. Réponses: 6
    Dernier message: 29/04/2010, 11h06
  3. Transférer une image vers GWT
    Par Iron Bull dans le forum GWT et Vaadin
    Réponses: 4
    Dernier message: 18/01/2010, 22h05
  4. Réponses: 0
    Dernier message: 01/11/2007, 23h46
  5. lire une image au format RAW
    Par Anonymous dans le forum OpenGL
    Réponses: 5
    Dernier message: 20/05/2002, 00h11

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