0

我需要将 pgm 格式的 base64Binary-string 转换为 android 中的位图。所以我没有通常的 base64 编码位图。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 转换为有效的字节数组以创建有效的位图?

4

2 回答 2

2

我认为您的 Base64 解码很好。但 AndroidBitmapFactory可能没有直接支持 PGM 格式。我不确定如何为其添加支持,但似乎您可以很容易地Bitmap使用其中一种createBitmap(...)工厂方法创建一个。

有关如何解析标头的详细信息,请参阅PGM 规范,或查看我的 Java SE 实现(如果您环顾四周,您还会发现一个支持 ASCII 读取的类,如果需要)。

也可能是没有标题,您可以从 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);
于 2014-11-15T19:37:25.910 回答
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;
}
于 2015-06-11T12:49:14.623 回答