Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/209.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 加载和裁剪位图时不会出现内存不足异常_Android_Image - Fatal编程技术网

Android 加载和裁剪位图时不会出现内存不足异常

Android 加载和裁剪位图时不会出现内存不足异常,android,image,Android,Image,我需要从Facebook、Instagram或设备本身裁剪图像。在用户流结束时(他选择了它们),所有的图像都应该发送到服务器。但是它们都是相同的宽高比(例如3/2),因此我需要手动裁剪图像 下面是我的上传服务和裁剪的一个简单示例: Bitmap bitmap = ImageLoading.getLoader(UploadService.this).loadImageSync(path); //crop calculations Bitmap croppedBitmap = Bitmap.crea

我需要从Facebook、Instagram或设备本身裁剪图像。在用户流结束时(他选择了它们),所有的图像都应该发送到服务器。但是它们都是相同的宽高比(例如3/2),因此我需要手动裁剪图像

下面是我的上传服务和裁剪的一个简单示例:

Bitmap bitmap = ImageLoading.getLoader(UploadService.this).loadImageSync(path);
//crop calculations
Bitmap croppedBitmap = Bitmap.createBitmap(bitmap, x, y, w, y);
String croppedPath = saveCroppedImage(croppedBitmap);
然后,我从文件系统中读取这个文件,并将其编码到BASE64以将其发送到后端

当我必须对多个图像执行此操作时,我经常会遇到OOM异常。也许我走错了方向。。在服务器端进行裁剪实际上是我最不想做的事情,因为这样后端就必须查询Facebook或Instagram

加载位图的缩放版本不是一个选项,我不会在设备上显示它

我试过:

  • System.gc()
  • Bitmap.recycle()
  • 我真的应该在清单中使用largeHeap吗

注意:我也在为用户流使用Universal Image Loader,这就是为什么我也在上载服务中使用它。

我认为您应该在AndroidManifest文件中添加largeHeap=true

其次,如果您使用的是Universal ImageLoader,则可以下载较小尺寸的位图。请查看此代码:

ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size
Bitmap bmp = imageLoader.loadImageSync(imageUri, targetSize, options); // This bitmap will be of specified size.

您可以通过以下链接进一步阅读。

我认为您应该在AndroidManifest文件中添加largeHeap=true

其次,如果您使用的是Universal ImageLoader,则可以下载较小尺寸的位图。请查看此代码:

ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size
Bitmap bmp = imageLoader.loadImageSync(imageUri, targetSize, options); // This bitmap will be of specified size.

您可以通过以下链接进一步了解。

GC不是您的问题。Android堆变得支离破碎;没有足够大的单个空闲块来满足分配请求。尝试重用
Bitmap
对象(请参见
BitmapFactory.Options
上的
inBitmap
),这可能需要自己加载图像,而不是使用UIL。理想情况下,您可以找到一种不需要创建图像另一个副本的裁剪方法(就像
createBitmap()
可能做的那样)。您还可以在
savecropedimage()
中做一些事情来提供帮助。谢谢您的评论!savecropedimage()只使用FileOutputStream并将其压缩为PNG 100。我真的承受不起质量损失。我看过inBitmap,但这似乎限制了不同图像大小的使用。“我看过inBitmap,但这似乎限制了不同图像大小的使用”——API级别19+提供了更大的灵活性,但是是的,它是有限的。另一方面,您可能没有太多的选项,除非您想开始使用NDK并在C/C++中进行图像裁剪。是的,我注意到它在19++上更灵活。我并没有真正了解使用NDK如何改善内存管理?我可能不得不重新考虑整个方法,并最终进行服务器端裁剪。“在这里使用NDK如何改进内存管理?”--很简单:您没有使用Java堆。您可以访问整个免费系统RAM。如果将load crop和save logic移动到NDK中,它会运行得更快,并避免出现
OutOfMemoryError
。维护起来更麻烦,尤其是跨CPU体系结构。测试和填充也更繁琐。但是,你可能没有选择。请记住,即使您要求一个
大堆
,它也可能不是很大(例如Android One设备)。GC不是您的问题。Android堆变得支离破碎;没有足够大的单个空闲块来满足分配请求。尝试重用
Bitmap
对象(请参见
BitmapFactory.Options
上的
inBitmap
),这可能需要自己加载图像,而不是使用UIL。理想情况下,您可以找到一种不需要创建图像另一个副本的裁剪方法(就像
createBitmap()
可能做的那样)。您还可以在
savecropedimage()
中做一些事情来提供帮助。谢谢您的评论!savecropedimage()只使用FileOutputStream并将其压缩为PNG 100。我真的承受不起质量损失。我看过inBitmap,但这似乎限制了不同图像大小的使用。“我看过inBitmap,但这似乎限制了不同图像大小的使用”——API级别19+提供了更大的灵活性,但是是的,它是有限的。另一方面,您可能没有太多的选项,除非您想开始使用NDK并在C/C++中进行图像裁剪。是的,我注意到它在19++上更灵活。我并没有真正了解使用NDK如何改善内存管理?我可能不得不重新考虑整个方法,并最终进行服务器端裁剪。“在这里使用NDK如何改进内存管理?”--很简单:您没有使用Java堆。您可以访问整个免费系统RAM。如果将load crop和save logic移动到NDK中,它会运行得更快,并避免出现
OutOfMemoryError
。维护起来更麻烦,尤其是跨CPU体系结构。测试和填充也更繁琐。但是,你可能没有选择。请记住,即使您要求一个
大堆
,它也可能不是很大(例如,Android One设备)。恐怕这里不允许加载较小版本的位图。我们需要全质量的。我想我可能不得不使用largeHeap,但这听起来像是一个肮脏的代码。我恐怕在这里不能选择加载较小版本的位图。我们需要全质量的。我想我可能不得不使用largeHeap,但它听起来像一个肮脏的代码。