Question

I am decoding base 64 encoded images on Android(Java). It works for most of the images, but for some of the image binaries it returns null. If I use an online decoder, the binary in question works fine, which tells me the format is correct.

The piece of code on the Base64.class file that messes up is

if (!decoder.process(input, offset, len, true)) {
    throw new IllegalArgumentException("bad base-64");
}

// Maybe we got lucky and allocated exactly enough output space.
if (decoder.op == decoder.output.length) {
    return decoder.output;
}

// Need to shorten the array, so allocate a new one of the
// right size and copy.
byte[] temp = new byte[decoder.op];
System.arraycopy(decoder.output, 0, temp, 0, decoder.op);
return temp;

For the images that fail, it goes through the

maybe we got lucky check, and returns decoder.output and directly jumps to return temp, which inturn returns null

. But for the images that work it does not enter that if and returns a non null temp variable. Is there a known issue with this?

UPDATE

Invoking code

 //This decodedString is null
    byte[] decodedString = Base64.decode(
                        data, Base64.DEFAULT);
                Bitmap setBMPPath = BitmapFactory.decodeByteArray(decodedString, 0,
                        decodedString.length);

                qImage.setImageBitmap(setBMPPath); 

EDIT

Turns out that the method is returning a value. Thanks @DavidEhrmann for the help. The error is actually in the next step where I am converting the decodestring into a bitmap.

public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) {
        if ((offset | length) < 0 || data.length < offset + length) {
            throw new ArrayIndexOutOfBoundsException();
        }
        Bitmap bm = nativeDecodeByteArray(data, offset, length, opts);
        if (bm == null && opts != null && opts.inBitmap != null) {
            throw new IllegalArgumentException("Problem decoding into existing bitmap");
        }
        return bm;
    }

Here bm is returning null! Basically this call

Bitmap bm = nativeDecodeByteArray(data, offset, length, opts);

is null but since opts != null && opts.inBitmap != null are not true it does not throw the IllegalArgumentException and just returns bm as null. Any ideas why?

UPDATE

I see an error in the log which says Skia --decoder decode returns false. I've tried every answer to every such question on SO and its still not working .

My Base64 code: http://pastebin.com/pnbqqg97

If its posted on a website that decodes online, it spits out the right image, but the bitmap decoder fails.

UPDATE - SOLUTION TO MY PROBLEM

As it turns out, the binary encoding was being done on a PNG file, and then being reconverted back into a bmp file, bmp to bmp seems to work in all cases. But I am surprises some png's converted also work! BUt for me having the original image as a bmp is a problem because of the size, is there a way I can decode a PNG base 64 in Android reliably without using the BitMap factory>?

ANSWER

Turns out the image was actually invalid at one character point :O But it for some reason wasnt picked up by the online decoder but was in the code shown above. Make sure you check the code to see that you are not replacing any of the image base64 characters. Even one off can set it to go haywire as I found out

Was it helpful?

Solution

Take a look at Why does BitmapFactory.decodeByteArray return null?. What's a bit strange is that data you pastebinned looks like a valid PNG.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top