rococo
rococo

Reputation: 2657

Reading a PNG file and retaining the correct format in Java

I'm trying to read a PNG file and then send the data out as a response to an HTTP request.

When I rename the original PNG file to a .txt and open it in an editor, I see the contents are something like this

8950 4e47 0d0a 1a0a 0000 000d 4948 4452
0000 074c 0000 0632 0806 0000 00bc 541d
2300 0000 0467 414d 4100 00b1 8e7c fb51
9300 0000 2063 4852 4d00 0087 0f00 008c
0f00 00fd 5200 0081 4000 007d 7900 00e9

However, when I try to manually read it and store it as a String in Java, I get a result like this:

�PNG

���
IHDR��L��2����T#���gAMA����|�Q���� cHRM���������R���@��}y�����<����s<�w��
/iCCPICC Profile��HÇ�wTT��Ͻwz��0�z�.0��. Qf���Ml��@DE�����H��b!(�`HPb0�ï

As a result, I get an error in browsers saying the image is malformed.

Seeing as the output contains a couple readable things like "PNG", I believe I'm changing the encoding when I read it. But, I have no idea how to make it retain the "correct" format / encoding. Here are two different approaches I've tried, both of which result in similarly broken results.

        InputStream inputStream = NewWebserverLauncher.class.getClassLoader().getResourceAsStream(url);
        if (inputStream == null) {
            // todo: error
            return "NO INPUT STREAM. Looked for \"" + url + "\"";
        }
        ByteArrayOutputStream result = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            result.write(buffer, 0, length);
        }
        return result.toString();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();

Would appreciate pointers on how I can read the PNG correctly!

Upvotes: 4

Views: 1684

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500445

However, when I try to manually read it and store it as a String in Java

You shouldn't do that. It's just not text.

Would appreciate pointers on how I can read the PNG correctly!

Don't try to store binary data as if it's text data.

Your code that copies the data into a ByteArrayOutputStream is broadly correct - until the last line, when you convert it into a string. Just don't do that. Call toByteArray() instead.

The text you've shown at the start of your post is the hex representation of the bytes. You didn't say what you opened it in, but I suspect it's some program that is either dedicated to editing binary files, or something that recognizes that you're opening a file which really isn't text, despite the file extension.

You've written a comment indicating that the library you're using only allows you to send a string as a response. If that's really the case, use a different library. Any library which really assumes that every HTTP response is text is fundamentally broken, and you may well find there are many other problems with it. I would look carefully first though - you may well find there are ways of sending binary data, and you just haven't found them yet. You may want to post a new question that's specifically about "How can I send a binary response using library X?" rather than about how to treat binary data as a string.

Upvotes: 5

Related Questions