h0tpot8o
h0tpot8o

Reputation: 23

Render byte[] from Java API as an image in Angular 2

i've been stuck on this one for a while and any help is appreciated. Images are stored as Base64 and i just can't get the setup right:

I have the following API in my ProductRestController

@GetMapping("/{id}/image")
public byte[] getProductImageByProductId(@PathVariable Long id) {
    return productFacade.getProductImageByProductId(id);
}

my product.service.ts:

  getProductImageByProductId(productId: number) {
    return this.http.get(ServiceConfig.serverBaseUrl + `/product/${productId}/image`, {responseType: 'arraybuffer'});
  } // I guess it has to be something with the responseType? I tried all types..

in my select-product.component.ts:

  getProductImage(product: Product) {
      this.productService.getProductImageByProductId(product.id).subscribe( base64 => {
        if(base64) {
          this.base64 = 'data:image/jpg;base64,' + base64; // this.base64 is a String
        }
        else {this.base64 = 'assets/no-image-icon.png';}
      });

and finally the html:

      <img [escape]="false"
           pTooltip='<img style="max-height: 100%; max-width: 100%" src="{{base64}}" >'
           tooltipPosition="right" (mouseover)="getProductImage(product)"
           src="assets/eye-icon.png" style="max-width: 100%; width: 80%; margin-bottom: 3px">

}

It should show an image in a tooltip when you hover on an icon, but whatever responseType i'm setting in my service, it will give me a parsing error with in the response some gibberish in the style of : %�S���cs5���&D�TdE£t6�U�e���u��F'���������������Vfv��������7GWgw��������5!1AQaq"2...

Thank you for your help!

Upvotes: 1

Views: 804

Answers (2)

Traycho Ivanov
Traycho Ivanov

Reputation: 3207

What do you think about returning base64 encoded string as response ?

@GetMapping("/{id}/image")
public String getProductImageByProductId(@PathVariable Long id) {
    byte[] image = productFacade.getProductImageByProductId(id);
    return Base64.getEncoder().encodeToString(image);
}

Note: Is you have images as bas64 in the db, just return it as response.

Upvotes: 0

CaspianTerrazzo
CaspianTerrazzo

Reputation: 2148

You should use responstype blob. since you return byte and not base64 string.

Because this Java getmapping tells you "byte[]"

@GetMapping("/{id}/image")
public byte[] getProductImageByProductId(@PathVariable Long id) {
    return productFacade.getProductImageByProductId(id);
}
  getProductImageByProductId(productId: number): Observable<any> {
    return this.http.get<Observable<any>>(ServiceConfig.serverBaseUrl + `/product/${productId}/image`, {responseType: 'blob'});
  } /
   export class SelectProductComponent{

    constructor(private sanitizer:DOMSanitizer, /*other params*/){}


    public someMethod(product:Product):void{
    this.productService.getProductImageByProductId(product.id).subscribe( data =>{
         var reader = new FileReader();
         const blob = new Blob([data], {
            type: 'image/jpeg'
             });
         //EDIT: Don't use function. my bad
         reader.onloadend = () => {
           const untrustedData = reader.result; 
           this.base64 = this.sanitizer.bypassSecurityTrustUrl(untrustedData);          
         } 
         reader.readAsDataURL(blob); 
         
       }
 
    }

   
       // also you can use ObjectURL if you 
      //just want the image and don't need the conversion to base64

   
        public someOtherMethod(product:Product):void{
    this.productService.getProductImageByProductId(product.id).subscribe( data =>{
            const blob = new Blob([data], {
            type: 'image/jpeg'
             });
           const objectUrl = URL.createObjectURL(blob);
           this.image = this.sanitizer.bypassSecurityTrustUrl(objectURL);
         }
       }
 
    }

}

Upvotes: 1

Related Questions