0

I am making an API call to an external app (this app converts all images originally loaded into it to PNG). If the image was originally loaded into that app as a PNG then RestTemplate can get it fine. If it was originally loaded as something else then converted to PNG the below code throws an error when trying to get it using RestTemplate in Spring 4.1.1. The image displays fine on the external app.

Caused by: javax.imageio.IIOException: I/O error reading PNG header! at com.sun.imageio.plugins.png.PNGImageReader.readHeader(PNGImageReader.java:315) ~[na:1.8.0_20] at com.sun.imageio.plugins.png.PNGImageReader.readMetadata(PNGImageReader.java:654) ~[na:1.8.0_20] at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1248) ~[na:1.8.0_20] at com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1606) ~[na:1.8.0_20] at org.springframework.http.converter.BufferedImageHttpMessageConverter.read(BufferedImageHttpMessageConverter.java:174) ~[BufferedImageHttpMessageConverter.class:4.1.1.RELEASE] at org.springframework.http.converter.BufferedImageHttpMessageConverter.read(BufferedImageHttpMessageConverter.java:67) ~[BufferedImageHttpMessageConverter.class:4.1.1.RELEASE] at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:104) ~[HttpMessageConverterExtractor.class:4.1.1.RELEASE] at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:576) ~[RestTemplate.class:4.1.1.RELEASE] ... 74 common frames omitted Caused by: javax.imageio.IIOException: Bad PNG signature! at com.sun.imageio.plugins.png.PNGImageReader.readHeader(PNGImageReader.java:242) ~[na:1.8.0_20]

BufferedImage image = restTemplate.getForObject(getPhotoUrl(), BufferedImage.class, Collections.EMPTY_MAP);
kevin15k
  • 11
  • 1
  • 5
  • 1
    You can set log level of spring to DEBUG so that you can see more details about the problem. Additionally it would more helpful for readers if you would paste the whole stack trace. Especially the "Caused by:" section of the stack trace is very important to understand the underlying problem. – Selim Ok Nov 20 '14 at 21:33
  • Add in all of your calling code and object class code which will help debug you issue further – Aeseir Nov 20 '14 at 23:45
  • You do not really explain what happened to the image, but the error says : what you get is not a valid PNG image. Dowload it directly from the converting app, and control what its format really is. – Serge Ballesta Nov 24 '14 at 16:57

1 Answers1

1

Instead of using getForObject method to get BufferedImage, using exchange method to get byte array back. Images that have bad PNG headers now display in the browser.

//Set HttpHeaders object
List<MediaType> acceptableMediaTypes = new ArrayList<>();
acceptableMediaTypes.add(MediaType.IMAGE_PNG);
HttpHeaders headers = new HttpHeaders();
headers.setAccept(acceptableMediaTypes);

//Get image from external app with API call
ResponseEntity<byte[]> responseEntity = restTemplate.exchange(getPhotoUrl(), HttpMethod.GET, new HttpEntity<byte[]>(headers), byte[].class);
byte[] image = responseEntity.getBody();

//Display image in browser
if(image != null) {
    InputStream in = new ByteArrayInputStream(image);
    BufferedImage bImageFromConvert = ImageIO.read(in);

    if(bImageFromConvert != null) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(bImageFromConvert, "png", baos);
        byte[] data = baos.toByteArray();
        response.setContentType(MediaType.IMAGE_PNG_VALUE);
        response.getOutputStream().write(data);
    }
}
kevin15k
  • 11
  • 1
  • 5