Android将base64Binary pgm解析为Bitmap

时间:2014-10-10 13:32:48

标签: java android bitmap base64 pgm

我需要将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转换为有效的字节数组以创建有效的位图?

2 个答案:

答案 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;
}