1

I want to use Gravatar but I don't want to publish users MD5 hashes of their e-mail addresses. And there is more potential problems. So I decided to download them and store them in my database.
But I have a problem with such a simple task as my profile picture (Earlybird) looks bad after downloading:

enter image description here

This is the code I used.

try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
    final URL url = new URL("http://www.gravatar.com/avatar/" + account.getGravatarHash() + "?d=identicon");
    final BufferedImage image = ImageIO.read(url);
    ImageIO.write(image, "jpg", baos);
    pic = baos.toByteArray();
} catch (IOException e) {
    e.printStackTrace();
}

Value in pic is then directly stored to the database. Other pictures in my database are stored fine so problem must be in these lines.

EDIT:
I just partially fix the problem by changing "jpg" for a "png" even thought Gravatar tutorial is mentioning "jpg". Also I don't want to specify image format (unless all Gravatars are png). Can I avoid that? I want just save the bytes I get.

Community
  • 1
  • 1
icl7126
  • 5,740
  • 4
  • 53
  • 51
  • Unit tests save the world. Test your pic byte[] against the same picture loaded from the local file. – ursa Oct 12 '15 at 22:26

2 Answers2

0

Browsers in most cases work with raw bytes. However it is highly appreciated to send "Content-Type: image/..." header for each image.

When you save bytes in DB you also have to

  1. either save image content type, provided by Gravatar for this image or
  2. convert image into your default format, so you can to hardcode content type for all images from your DB

To get headers, provided by Gravatar, you can use Apache HTTP Client.

To convert image into your preferred format, you can use ImageIO.

ursa
  • 4,404
  • 1
  • 24
  • 38
  • You can get content type even after it's stored in database, you can identify file format. A least for images. But looks like it works for Chrome and Firefox even when you don't specify content type in response or even give wrong one like `"image/jpeg"` for `png`. – icl7126 Oct 12 '15 at 23:14
  • Yes, clever browsers identifies image format themselves, without content-type hint from server. But your problem raises just from here - stupid browsers relays on this header – ursa Oct 13 '15 at 10:48
0

I found one similar problem with working solution:

try (ByteArrayOutputStream baos = new ByteArrayOutputStream()){
    final URL url = new URL("http://www.gravatar.com/avatar/" + account.getGravatarHash() + "?d=identicon");
    InputStream inputStream = url.openStream();
    byte[] buffer = new byte[1024];
    int n;
    while (-1 != (n = inputStream.read(buffer))) {
        baos.write(buffer, 0, n);
    }
    inputStream.close();
    pic = baos.toByteArray();
} catch (IOException e) {
    e.printStackTrace();
}

Looks like this works with png and jpg Gravatars.

Community
  • 1
  • 1
icl7126
  • 5,740
  • 4
  • 53
  • 51