0

我正在尝试设计一种通过 Couchbase-Lite (Android) 存储多个高质量图像的方法,方法是将它们转换为 Base64 字符串并将它们存储在 Couchbase 文档中,而不会完全耗尽内存。

我当前的实现循环遍历本地存储的图像文件的名称列表(“image_file_names”),依次解码每个文件,捕获 ByteArray 表示,编码为 Base64 字符串,然后将该值插入 ArrayList。

这里需要注意的是:1)图像质量必须是最高可用的,2)图像的数量是完全可变的(0个或更多,没有限制)

我目前的实现如下:

ArrayList<byte[]> image_data_byte = new ArrayList<byte[]>();
ArrayList<String> image_data_string = new ArrayList<String>();

for (String image_file_name : image_file_names)
{
     String image_file_path = files_directory + File.separator + image_file_name;
     File image_file = new File(image_file_path);
     {
         ByteArrayOutputStream bitmap_stream = new ByteArrayOutputStream();
         Bitmap bitmap = BitmapFactory.decodeFile(image_file.getAbsolutePath());
         bitmap.compress(CompressFormat.JPEG, 100, bitmap_stream);
         image_data_byte.add(bitmap_stream.toByteArray());
         String image_string = Base64.encodeToString(bitmap_stream.toByteArray(), Base64.NO_WRAP);
         image_data_string.add(image_string);
     }
}

到目前为止,我发现的每条信息都与显示图像(通过异步任务)或通过 HTTP 上传图像有关,但就我而言,我并没有尝试显示图像,所有上传都是通过 Couchbase 处理——我试图在将文档插入 Couchbase 之前达到我有字符串表示的点。

失败的行具体是:

String image_string = Base64.encodeToString(bitmap_stream.toByteArray(), Base64.NO_WRAP);

和:

 Caused by: java.lang.OutOfMemoryError

任何指导将不胜感激。

4

3 回答 3

0

质量为 100 的情况下,在您的代码中,每个图像的内存都是其大小的两倍,随着图像数量的增加,这最终会失败。

为什么要保留重复信息(一个在字节数组中,一个在字符串数组中)?无论如何,最好的做法是将此数据写入 sqlite 数据库并根据需要检索它,并且不要保留重复的版本。使用 Base64 的字节数组和字符串数组之间的转换非常快。

这样,图像的数量将没有限制(还有设备存储限制)

于 2015-01-28T22:35:50.283 回答
0

如果图像不是太昂贵的格式(.bmp 通常效率低下),您可以(至少对于 JPEG)将图像加载为二进制文件,而不是图像,然后立即将其编码为 base64 字符串。这更快并且使用更少的内存/垃圾收集。

更好的办法是存储byte[]并动态生成 Base64 字符串。

更好的办法是移动 for 循环,这样就不需要列表,并且为每个文件生成和写入 Base64 字符串。

于 2015-01-29T02:29:26.677 回答
0

请注意,Couchbase Lite 存储附件。您最好将图像附加到 JSON 元数据。实际上,这就像@stopBugs 提到的那样,但使​​用的是 Couchbase 而不是 sqlite。

于 2015-01-29T02:05:51.823 回答