6

I've encoded a image into base64 using the org.apache.axis.encoding.Base64 class. My code:

public String get64EncodedPhotoForUser(User user) {

        // Path to image
        String path = "some path to the jpg file on the server";

        // Read image from server
        String base64Image = null;

        try {

            BufferedImage bufferedImage = ImageIO.read(new File(path));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "jpg", baos);
            baos.flush();
            byte[] imageInByte = baos.toByteArray();
            baos.close();
            base64Image = Base64.encode(imageInByte);

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        return base64Image;

    }

As you can see I first convert the image into a byte array as that is what the encode method expects.. Everything seems to work fine, I get my encoded string back and it seems to be a correctly encoded string. Worth mentioning here that some online decoders can correctly decode the image while others again can't, which I thought is odd..

When I try and display the image in my HTML:

<img ng-src="data:image/png;base64,/9j/4AAQSkZJRgABAgAAA..." id="avatar">

It doesn't work. I just get that 'missing image' icon you get when you're pointing your html to an image that doesn't exist.

I've copied and pasted the encoded string into a jsfiddle you can check out here

PS - I also take the base64 string and I pass it from the server to the client in a JSON object along with some other things. The Base64 string you're seeing in the jsfiddle is what I get back on the client-side. Could it be that the encoded string could perhaps have been corrupted or modified, when it was passed over the network?

  • 1
    Quick question: What steps did you take from the point where you output the base 64 encoded string in Java and where you create the Fiddle? This is where the final character is being converted to explicit unicode. – Tim Biegeleisen Aug 28 '15 at 09:19
  • I basically take that encoded String, set it as a property on a 'User' POJO I created, I then convert that User POJO to a JSON object using Gson (https://github.com/google/gson), which I then send to the client with a HttpServletResponse, setting the content type to "text/json" –  Aug 28 '15 at 09:23

2 Answers2

3

The equals sign at the end of your base 64 encoded string has been converted to its unicode format (\u003d):

/9j/4AAQSkZJR...IQd6QknrS54460h60BY//9k\u003d
  ^                                     ^
 start                                 end

When I changed the \u003d at the end of the string to = in my <img> tag, the image loaded fine in my Chrome browser. Here is the code I used to get the image to load:

<IMG src="data:image/jpeg;base64,/9j/4AAQSkZJR...IQd6QknrS54460h60BY//9k=">

Note that deleting the unicode character also seemed to work in the browser.

What is happening:

I tested your Java code using the Apache Axis Base64.encode() method, and the output looks correct, i.e. the string ends in an equals sign as expected. However, in your JS Fiddle which you made available, the unicode character appears. Based on this GitHub blog, it appears that the Gson library HTML escapes the last character for some reason. Regardless of whether or not it's a bug or a bad feature, Gson provided a way to get around this:

Gson gson = new GsonBuilder().disableHtmlEscaping().create();

Build your JSON object using this version of Gson object and you should not have the escaping problem.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • It's amazing you figured that out. Do you perhaps know why it's there and what I can do to not get that checksum appended to the string? PS - Just checked, and when you remove that it does work! –  Aug 28 '15 at 08:32
  • 1
    I was staring at the end of the Base 64 encoded string, and I saw what appeared to be a unicode character staring back at me. I searched the whole string, and low and behold I found no others. The bigger question is why online Base 64 decoders such as [this one](http://www.motobit.com/util/base64-decoder-encoder.asp) were able to decode and produce an image file which, for example, MS Paint was able to open, but Chrome chokes on it. – Tim Biegeleisen Aug 28 '15 at 08:35
  • Firefox also doesn't like it. –  Aug 28 '15 at 08:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/88169/discussion-between-dean-grobler-and-tim-biegeleisen). –  Aug 28 '15 at 09:09
  • Solved! I can't thank you enough, the extent you went to to help me out is just phenomenal. I know simple 'thank you' comments are discouraged here, but I'm just so thankful that you went the extra mile here. :) –  Aug 28 '15 at 09:39
  • 1
    Thanks, Dean. I love solving tough problems, and when I can't readily explain them, I love them even more. – Tim Biegeleisen Aug 28 '15 at 09:40
1

In your Java, you're writing a jpg image but you are showing it in HTML as png.

raduation
  • 792
  • 5
  • 11
  • 2
    If that's the issue I'm going to kick my own ass.. let me fix that. –  Aug 28 '15 at 08:16
  • 2
    Nope sorry, I change the HTML to 'jpg' as well as 'jpeg' and I still have the same issue... Good eye you got there though. –  Aug 28 '15 at 08:18
  • There may be a number of things going on, whether the charset is the issue, or the encoding from Java is the issue. Please read this discussion http://stackoverflow.com/questions/8499633/how-to-display-base64-images-in-html – raduation Aug 28 '15 at 08:21
  • Please see my edited question, the base64 string gets passed over http to the client. Could the string get corrupted or modified in that proces? –  Aug 28 '15 at 08:29