我需要将pgm格式的base64Binary-string转换为android中的位图。所以我没有通常的base64编码的Bitmap。 base64binary-string来自xml文件
<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
我想我明白pgm图像通常存储为ASCII(如我的xml)或二进制(0..255)。我还认为Base64.decode
需要二元变体,而不是我拥有的ASCII。
但是BitmapFactory.decodeByteArray
无法理解解码后的字节数组并返回null。
那么如何将base64binary-pgm-ASCII-string转换为有效的字节数组以创建有效的位图?
答案 0 :(得分:1)
我认为您的Base64解码很好。但Android的BitmapFactory
可能没有直接支持PGM格式。我不确定如何添加对它的支持,但似乎您可以非常轻松地使用Bitmap
工厂方法之一创建createBitmap(...)
。
有关如何解析标题的详细信息,请参阅PGM spec,或查看my implementation for Java SE(如果您环顾四周,如果需要,您还会找到支持ASCII读取的类。)< / p>
也可能没有标题,你可以从XML获得高度/宽度。在这种情况下,dataOffset
将在0
以下。
解析标题时,您知道宽度,高度以及图像数据的开始位置:
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);
答案 1 :(得分:0)
感谢您的回答! 你今天解决了我!
我在代码中发现了一点错误,索引i从未初始化或递增。 我更正了你的代码并进行了测试,这是我的代码:
private static Bitmap getBitmapFromPgm(byte[] decodedString, int width, int height, int dataOffset){
// Create pixel array, and expand 8 bit gray to ARGB_8888
int[] pixels = new int[width * height];
int i = 0;
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;
i++;
}
}
Bitmap pgm = Bitmap.createBitmap(pixels, width, height, android.graphics.Bitmap.Config.ARGB_8888);
return pgm;
}