I need to convert a base64Binary-string in the format pgm to a bitmap in android. So I don't have an usual base64-encoded Bitmap. The base64binary-string came from a xml file
<ReferenceImage Type="base64Binary" Format="pgm" WidthPX="309" HeightPX="233" BytesPerPixel="1" >
NDY4Ojo9QEFDRUVHRklLTE9OUFFTU1VWV1hZWltZWVlZWlpbW1xdXmBgYmJjZGNlZWRkZGRlZmZnZ2ZnaWpqa21ub29ubm9vb3BwcHBxcHFyc3FzcnJzcnJydH[...]VlaW1xbWltcXFxcXFxd
.
Pattern.compile("<ReferenceImage .*>((?s).*)<\\/ReferenceImage>");
...
String sub = r; //base64binary string pattern-matched from xml file
byte[] decodedString = Base64.decode(sub.getBytes(), Base64.NO_WRAP); //probably wrong decoding (needs to be ASCII to binary?)
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); //always null due to wrong byte-array
I think I understand that pgm images are typically stored as ASCII (like in my xml) or binary (0..255). I also think that Base64.decode
needs the binary-variant, not the ASCII that I have.
However BitmapFactory.decodeByteArray
doesn't understand the decoded byte-array and returns null.
So how can I convert my base64binary-pgm-ASCII-string to a valid byte-array in order to create a valid bitmap?
I think your Base64-decoding is fine. But Android's BitmapFactory
probably has no direct support for PGM format. I'm not sure how to add support to it, but it seems you could create a Bitmap
using one of the createBitmap(...)
factory methods quite easily.
See PGM spec for details on how to parse the header, or see my implementation for Java SE (if you look around, you'll also find a class that supports ASCII reading, if needed).
Could also be that there's no header, and that you can get the height/width from the XML. In that case, dataOffset
will be 0
below.
When the header is parsed, you know width, height and where the image data starts:
int width, height; // from header
int dataOffset; // == end of header
// Create pixel array, and expand 8 bit gray to ARGB_8888
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int gray = decodedString[dataOffset + i] & 0xff;
pixels[i] = 0xff000000 | gray << 16 | gray << 8 | gray;
}
}
Bitmap pgm = Bitmap.createBitmap(metrics, pixels, width, height, BitmapConfig.Config. ARGB_8888);