68 votes

Obtenir une image à partir d'une API en Angular 4/5+ ?

Je suis nouveau dans le développement d'Angular 4. J'ai rencontré un problème lors de l'obtention de la réponse de l'API concernant l'affichage de l'image. Dans l'API, un fichier image a un flux d'entrée, je ne sais pas comment le récupérer et l'afficher correctement.

Quelqu'un peut-il le résoudre ?

J'ai essayé ça :

  • Image.Component.ts :

    this.http.get('http://localhost:8080/xxx/download/file/596fba76ed18aa54e4f80769')
             .subscribe((response) => { var blob = new Blob([response.text()], {type: "image/png"});
               console.log(blob);
               console.log(window.btoa(blob.toString()));           
    });

Résultat de ce => W29iamVjdCBCbG9iXQ== mais le format n'était pas correct

et j'ai essayé ceci aussi :

this.http.get('http://localhost:8080/xxx/download/file/596fba76ed18aa54e4f80769').map(Image=>Image.text())
  .subscribe(data => {
    console.log((data.toString()));   
});

Résultat comme ceci =>

 ����\ExifII*��7                                                      ��DuckyK��fhttp://ns.adobe.com/xap/1.0/<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.3-c011 66.145661, 2012/02/06-14:56:27        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmpMM:OriginalDocumentID="xmp.did:0280117407206811A2188F30B3BD015B" xmpMM:DocumentID="xmp.did:E2C71E85399511E7A5719C5BBD3DDB73" xmpMM:InstanceID="xmp.iid:E2C71E84399511E7A5719C5BBD3DDB73" xmp:CreatorTool="Adobe Photoshop CC 2014 (Windows)"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:7092a9cd-b3fd-bb49-b53c-9b6e1aa1ac93" stRef:documentID="adobe:docid:photoshop:40615934-3680-11e7-911d-f07c687d49b8"/> <dc:rights> <rdf:Alt> <rdf:li xml:lang="x-default">                                                      </rdf:li> </rdf:Alt> </dc:rights> <dc:creator> <rdf:Seq/> </dc:creator> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>���Photoshop 3.08BIMJZ%Gt6                                                      8BIM%�<".}��νz��܌��Adobed����  

mais j'ai utilisé pour encoder en utilisant window.btoa il devrait y avoir une erreur comme "not latin range".

0 votes

Vérifiez ce poste

2 votes

J'ai essayé ce lien mais il apparaît comme " unsafe:blob : localhost:4200/47c05912-5beb-41bf-a791-ca8f0d86f‌​6af net::ERR_UNKNOWN_URL_SCHEME" et que l'uri a une image directe

1 votes

@KarthicG Si vous utilisez Angular, vous pouvez obtenir cette erreur. Utilisez DomSanitizer.bypassSecurityTrustUrl pour le réparer.

185voto

Gregor Doroschenko Points 4796

Vous devez définir responseType: ResponseContentType.Blob dans vos paramètres GET-Request, car ainsi vous pouvez obtenir votre image en tant que blob et la convertir plus tard en source encodée en base64. Votre code ci-dessus n'est pas bon. Si vous voulez faire cela correctement, alors créez un service séparé pour obtenir les images de l'API. Parce qu'il n'est pas bon d'appeler HTTP-Request dans les composants.

Voici un exemple concret :

Créer image.service.ts et mettez le code suivant :

Angular 4 :

getImage(imageUrl: string): Observable<File> {
    return this.http
        .get(imageUrl, { responseType: ResponseContentType.Blob })
        .map((res: Response) => res.blob());
}

Angular 5+ :

getImage(imageUrl: string): Observable<Blob> {
  return this.httpClient.get(imageUrl, { responseType: 'blob' });
}

Important : Depuis Angular 5+, vous devez utiliser la nouvelle fonction HttpClient .

Le nouveau HttpClient renvoie JSON par défaut. Si vous avez besoin d'un autre type de réponse, vous pouvez le spécifier en paramétrant le paramètre responseType: 'blob' . Pour en savoir plus ici .

Maintenant, vous devez créer une fonction dans votre image.component.ts pour obtenir une image et la montrer en html.

Pour créer une image à partir de Blob, vous devez utiliser la fonction JavaScript FileReader . Voici la fonction qui crée une nouvelle FileReader et écouter l'événement load-Event de FileReader. En conséquence, cette fonction renvoie une image codée en base64, que vous pouvez utiliser dans l'attribut src de img :

imageToShow: any;

createImageFromBlob(image: Blob) {
   let reader = new FileReader();
   reader.addEventListener("load", () => {
      this.imageToShow = reader.result;
   }, false);

   if (image) {
      reader.readAsDataURL(image);
   }
}

Maintenant, vous devez utiliser votre création ImageService pour obtenir une image à partir de l'api. Vous devez vous abonner aux données et donner ces données à l'API. createImageFromBlob -fonction. Voici un exemple de fonction :

getImageFromService() {
      this.isImageLoading = true;
      this.imageService.getImage(yourImageUrl).subscribe(data => {
        this.createImageFromBlob(data);
        this.isImageLoading = false;
      }, error => {
        this.isImageLoading = false;
        console.log(error);
      });
}

Vous pouvez maintenant utiliser votre imageToShow -dans le modèle HTML comme ceci :

<img [src]="imageToShow"
     alt="Place image title"
     *ngIf="!isImageLoading; else noImageFound">
<ng-template #noImageFound>
     <img src="fallbackImage.png" alt="Fallbackimage">
</ng-template>

J'espère que cette description est claire et que vous pourrez l'utiliser dans votre projet.

Voir l'exemple fonctionnel pour Angular 5+ ici .

0 votes

@malkoto1 Je sais, parce que je n'ai pas le temps de mettre à jour cette réponse. Dans Angular 5, vous devez utiliser HttpClient au lieu de Http.

3 votes

J'ai réussi à le faire fonctionner avec HttpClient, mais il essaie d'analyser JSON et donne l'erreur suivante : SyntaxError : JSON.parse : caractère inattendu à la ligne 1 colonne 1 des données JSON. Je serai reconnaissant si vous avez le temps de le mettre à jour dans un futur proche :)

1 votes

Je dois aussi passer les en-têtes. Mon appel est donc : return this httpClient.get('url', {headers : this.httpHeaders}) ; Alors, comment dois-je passer {response-type : 'blob'} ?

14voto

angulaire 5 :

 getImage(id: string): Observable<Blob> {
    return this.httpClient.get('http://myip/image/'+id, {responseType: "blob"});
}

0 votes

Je dois aussi passer les en-têtes. Mon appel est donc : return this httpClient.get('url', {headers : this.httpHeaders}) ; Alors, comment dois-je passer {response-type : 'blob'} ?

1 votes

{ headers: this.httpHeaders, responseType: 'blob' }

0voto

Vitor Kevin Points 394

Il n'est pas nécessaire d'utiliser angular http, vous pouvez obtenir avec les fonctions natives js

// you will ned this function to fetch the image blob.
async function getImage(url, fileName) {
     // on the first then you will return blob from response
    return await fetch(url).then(r => r.blob())
    .then((blob) => { // on the second, you just create a file from that blob, getting the type and name that intend to inform

        return new File([blob], fileName+'.'+   blob.type.split('/')[1]) ;
    });
}

// example url
var url = 'https://img.freepik.com/vetores-gratis/icone-realista-quebrado-vidro-fosco_1284-12125.jpg';

// calling the function
getImage(url, 'your-name-image').then(function(file) {

    // with file reader you will transform the file in a data url file;
    var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onloadend = () => {

    // just putting the data url to img element
        document.querySelector('#image').src = reader.result ;
    }
})

<img src="" id="image"/>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X