我试图设法通过Couchbase-Lite(Android)将多个高质量图像存储到Base64 Strings并将它们存储在Couchbase文档中而不会完全耗尽内存。< / p>
我当前的实现循环遍历本地存储的图像文件的名称列表(&#34; image_file_names&#34;),依次解码,捕获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表示。
失败的行具体是:
String image_string = Base64.encodeToString(bitmap_stream.toByteArray(), Base64.NO_WRAP);
使用:
Caused by: java.lang.OutOfMemoryError
非常感谢任何指导。
答案 0 :(得分:0)
质量为100,在你的代码中,每个图像的内存耗费两倍于它的大小,最终会随着图像数量的增加而失败。
为什么要保留重复信息(一个在字节数组中,另一个在字符串数组中)? 无论如何,最好的做法是将这些数据写入sqlite数据库并根据需要检索它,并且不要保留重复的版本。使用Base64在字节数组和字符串数组之间进行转换非常快。
这样,图像数量就没有限制(设备存储限制也是如此)
答案 1 :(得分:0)
请注意Couchbase Lite stores attachments。您可能最好将图像附加到JSON元数据。实际上,这就像@stopBugs提到的那样,但是使用Couchbase而不是sqlite。
答案 2 :(得分:0)
如果图像格式不太昂贵(.bmp通常效率不高),您可以(至少对于JPEG)将图像加载为二进制文件,而不是图像,并立即将其编码为base64字符串。这样更快,并且使用更少的内存/垃圾回收。
最好是存储byte[]
并动态生成Base64字符串。
更好的方法是移动for循环以便不需要列表,并为每个文件生成和编写Base64字符串。