裁剪图像没有OutOfMemory - Android

Sep*_*ozi 8 android image crop

我想裁剪图像而不会出现OutOfMemory异常.
这意味着我有裁剪图像的x,y,宽度和高度,并希望裁剪原始图像而不将其带入内存.
是的,我知道这BitmapRegionDecoder是个好主意,但也许裁剪的图像太大,无法将其带入记忆中.

实际上我不想要拼写位图,只想将裁剪后的图像从源文件写入目标文件.


编辑:我想保存裁剪的图像,而不仅仅是显示它ImageView 我希望将其保存在新文件中而不会丢失尺寸

这是一个例子
在此输入图像描述

在这种情况下,裁剪的图像分辨率为20000x20000,下面的代码不能用于OOM:

BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = bitmapRegionDecoder.decodeRegion(new Rect(width / 2 - 100, height / 2 - 100, width / 2 + 100, height / 2 + 100), options);
mImageView.setImageBitmap(bitmap);
Run Code Online (Sandbox Code Playgroud)

使用inSampleSize减少原始图片大小是好的,但我保存的结果不再是20000x20000.

如何裁剪25000x25000并将20000x20000部分图像保存在文件中?

Dus*_*usk 1

简而言之,它需要大量的低级编程和优化。

\n\n

正如您所看到的,该区域的许多答案都指向位图压缩等的通用概念,这些概念确实适用于大多数问题,但不适用于您的问题。

\n\n

另外,答案中建议的 BitmapRegionDecoder 不会\xe2\x80\x99 正常工作。它肯定会阻止将整个位图加载到 RAM 中,但是裁剪后的图像呢?裁剪图像后,它会给你一个巨大的位图,无论如何,都会给你一个 OOM。

\n\n

因为您所描述的问题需要位图从磁盘写入或读取,就像从内存写入或读取一样;称为 BufferedBitmap(或类似)的东西,它通过将位图的小块保存到磁盘并稍后使用它们来有效地处理所需的内存,从而避免 OOM。

\n\n

任何其他想要解决扩展问题的解决方案只能完成一半的工作。为什么?因为裁剪后的图像本身对于内存来说可能太大(正如你所说)。

\n\n

然而,如果您不关心裁剪图像的质量与用户在裁剪图像时看到的质量相比,通过缩放解决问题并不是那么糟糕。这\xe2\x80\x99就是Google Photos所做的,它只是降低了裁剪图像的质量,非常简单!

\n\n

我还没有看到任何 BufferedBitmap 类(但如果有的话,那就太棒了)。它们肯定可以方便地解决类似的问题。

\n\n

您可以查看 Telegram 消息传递应用程序,该应用程序附带图像裁剪工具的开源实现;你猜对了,它可以处理所有与旧的 C 类似的令人讨厌的工作...因此,我们可能会得出这样的结论:一个好的全局解决方案(或者更好地说,几个适用的解决方案之一)似乎是处理磁盘的低级编程和记忆自己。

\n\n

我知道我的答案未能为您的问题提供任何复制粘贴式的解决方案,但至少我希望它能给您一些想法,我的朋友。

\n