skip to Main Content

I am returning an image source from my local file with MediaType.IMAGE_JPEG. I am able to see the image if I make a call via Postman, but I could not succeed displaying it on HTML.

@GetMapping(value = "/{id}/download")
  public ResponseEntity<Resource> download(@PathVariable UUID id, @RequestParam String key) {
    try {
      final Path file = Paths.get(String.format("%s/%s", "app/resource", key));
      final Resource resource = new UrlResource(file.toUri());

      if (resource.exists() || resource.isReadable()) {
        final HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.IMAGE_JPEG);
        httpHeaders.setContentDispositionFormData("attachment", resource.getFilename());

        return ResponseEntity.ok()
            .headers(httpHeaders)
            .body(resource);
      } else {
        // error
      }
    } catch (MalformedURLException e) {
      // error
    }
  }

I tried to display it without converting, but the HTML shows that the image is broken

1st attempt

<img :src=imageContent />

const { data } = await download(id, "test.jpeg");
this.imageContent = data;

I also tried to convert it to base64, but it didn’t work.

2nd attempt with base64

<img :src=imageContent />

const { data } = await download(id, "test.jpeg");
this.imageContent =
      "data:image/jpeg;base64," +
        Buffer.from(data, "binary").toString("base64");

I am not sure where I made a mistake. Do I need to refactor my backend code? How can I display the image that I return as a response?

2

Answers


  1. I would use decoding as a BLOB object :

    
        const { data } = await download(id, "test.jpeg");
        this.imageContent = 
          "data:image/jpeg;base64," +
            Buffer.from(data, "binary").toString("base64");
    
        // atob() of JavaScript to decode the base chain64 in a binary chain
        const decodedImageData = atob(this.imageContent); 
       
        // Create a BLOB object
        const blob = new Blob([decodedImageData], { type: 'image/jpeg' });
        
        // Create a blob object URL
        const imageURL = URL.createObjectURL(blob);
    
        this.imageURL = imageURL;
    
    

    And then establish the URL of the image on the image label:

        <img src="{{ imageURL }}" alt="Image description">
    
    Login or Signup to reply.
  2. Try to use folliwng MediaType: APPLICATION_OCTET_STREAM. It will look something like:

    // check if exists and is readable
    InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
    
    return ResponseEntity.ok()
            .headers(headers)
            .contentLength(file.length())
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(resource);
    

    Also, you could use ByteArrayResource:

    // prepare steps
    Path path = Paths.get(file.getAbsolutePath());
    ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(path));
    
    return ResponseEntity.ok()
            .headers(headers)
            .contentLength(file.length())
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(resource);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search