Android 抛出OutOfMemory错误(字节到Base64)

Android 抛出OutOfMemory错误(字节到Base64),android,android-studio,bitmap,Android,Android Studio,Bitmap,我有一个数据库,我有一些大图像要转换成base64。 当我把它保存到数据库时,我收到了这个错误 11-17 11:56:03.359 11549-11620/? E/art: Throwing OutOfMemoryError "Failed to allocate a 63489036 byte allocation with 16777216 free bytes and 47MB until OOM" 11-17 11:56:03.359 11549-11620/? E/AndroidRu

我有一个数据库,我有一些大图像要转换成base64。
当我把它保存到数据库时,我收到了这个错误

11-17 11:56:03.359 11549-11620/? E/art: Throwing OutOfMemoryError "Failed to allocate a 63489036 byte allocation with 16777216 free bytes and 47MB until OOM"
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime: FATAL EXCEPTION: Thread-792
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime: Process: com.juandirection, PID: 11549
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime: java.lang.OutOfMemoryError: Failed to allocate a 63489036 byte allocation with 16777216 free bytes and 47MB until OOM
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:635)
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:611)
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:649)
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at com.juandirection.Review$9.getParams(Review.java:206)
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at com.android.volley.Request.getBody(Request.java:468)
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:253)
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:227)
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:107)
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:97)
11-17 11:56:03.359 11549-11620/? E/AndroidRuntime:     at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:114)
我的图像大约为6MB。
有些大约只有KB。Kb图像工作正常,但当我上传6mb图像时,我发现了这个错误

  @Override
                protected Map<String, String> getParams() {
                    Map<String, String> parameters = new HashMap<String, String>();
                    //String filepath = "/storage/emulated/0/Pictures/20150426_085939.jpg";
                    String filepath = Global.SELECTED_IMAGES.get(valueThisIteration);
                    String newFilePath = filepath.substring(7,filepath.length());
                    File imagefile = new File(newFilePath);
                    FileInputStream fis = null;
                    try {
                        fis = new FileInputStream(imagefile);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }

                    Bitmap bm = BitmapFactory.decodeStream(fis);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    bm.compress(Bitmap.CompressFormat.JPEG, 70 , baos);
                    byte[] b = baos.toByteArray();
                    String encImage = Base64.encodeToString(b, Base64.DEFAULT);
                    parameters.put("latitude", Global.lat);
                    parameters.put("imagepath", encImage);
                    return parameters;
                }
@覆盖
受保护的映射getParams(){
映射参数=新的HashMap();
//字符串filepath=“/storage/emulated/0/Pictures/20150426_085939.jpg”;
字符串filepath=Global.SELECTED\u IMAGES.get(valueThisIteration);
字符串newFilePath=filepath.substring(7,filepath.length());
File imagefile=新文件(newFilePath);
FileInputStream fis=null;
试一试{
fis=新文件输入流(imagefile);
}catch(filenotfounde异常){
e、 printStackTrace();
}
位图bm=位图工厂.decodeStream(fis);
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG,70,baos);
字节[]b=baos.toByteArray();
字符串encImage=Base64.encodeToString(b,Base64.DEFAULT);
参数.put(“纬度”,Global.lat);
参数put(“imagepath”,encImage);
返回参数;
}

您可以尝试在
AndroidManifest.xml
文件的应用程序标记中设置
android:largeHeap=“true”
。如下所示:

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true" />


希望这能有所帮助。

不要在哈希映射或数组列表中存储任何位图或base64字符串。只需存储图像的路径,当您想使用图像时,从该路径获取位图或base64图像字符串。这是一种很好的做法,因此在内部

  Map<String, String> parameters = new HashMap<String, String>();
Map参数=新的HashMap();

此映射仅存储图像的地址路径

您必须更改图像的分辨率。Android根本无法存储这么大的图像,因为它占用了太多的内存。

尝试添加bm.recycle();你的图像分辨率是多少?据我所知,如果在没有位图的情况下将图像解码为位图,则需要4倍于内存中像素大小的计数(因此对于200万像素的图像,需要8兆字节)。字节数组也占用空间,基64字符串占用更多空间。图像为6mb。我查看了图像的细节,但分辨率不可用。这张图片是从我的设备图库(三星Galaxy s5)中拍摄的,很可能是16MP(因为Bitmapfactory想要分配64MB的ob内存)。你真的需要解码图像吗?您可以直接将fileinputstream转换为字节数组。你真的需要这个高分辨率吗?看看如何减少所需的内存。为了将其作为Base64保存到数据库,我真的需要对图像进行解码。当我更改bm.compress(Bitmap.CompressFormat.JPEG,70,baos)时;到bm.compress(Bitmap.CompressFormat.JPEG,10,baos);错误消失了。压缩的第二个参数是什么?这会影响图像的分辨率吗?是的,这是一个很好的做法。但我的应用程序需要一个离线数据库。因此,我通过网络服务器存储我的图像,并在用户在线时更新android应用程序的sqlite数据库。这样用户仍然可以查看图像。所以我需要保存base64图像并对其进行解码。当您在数据库中插入base64字符串时,首先从hashnap获取图像路径,然后从该路径逐个获取base64字符串,不要在hashmap中存储所有图像base64字符串。好的,先生。我试试你的建议。但我使用的是StringBuilder,是否有任何参数可以放置?您在哪里使用StringBuilder?对不起。我是说,我怎样才能改变决议?不是这个尺寸。我的意思是,它与我上传的图像大小相同,但与原始图像不一样清晰。您必须更改bm.compress()中的第二个参数。第二个参数是质量(1-100),int,java.io.OutputStream)