问题 在iOS中处理大图像


我想让用户在不限制大小的情况下选择照片,然后进行编辑。

我的想法是创建一个与用于编辑的屏幕大小相同的大型照片的缩略图,然后,在编辑完成后,使用大型照片进行与缩略图相同的编辑。

我用的时候 UIGraphicsBeginImageContext 要创建缩略图图像,它将导致内存问题。

我知道由于硬件限制很难直接编辑整个大图像,所以我想知道是否有一种方法可以将大图像下采样到不到2048 * 2048而没有内存问题?

我发现有一个 BitmapFactory 有一个类 inSampleSize 可以在Android平台下采样照片的选项。如何在iOS上完成?


13191
2018-04-16 17:19


起源

您可以使用NSData * data = [NSData dataWithContentsOfFile:path options:NSDataReadingMappedAlways error:&error];访问图像数据而不将其加载到内存中。 - Sten
感谢Sten的提示,我尝试过使用NSDataReadingMappedAlways选项,但它仍然会崩溃10000 * 10000图像,我认为无论如何加载图像,使用UIGraphicsBeginImageContext缩放原始图像需要内存中的整个位图。有什么办法可以在将jpeg / png文件加载到内存时对图像进行缩减采样吗? - lingtianlan


答案:


您需要使用处理图像加载 UIImage 它实际上并没有将图像加载到内存中,然后以您想要的结果图像的大小创建位图上下文(因此这将是使用的内存量)。然后你需要迭代多次从原始图像中绘制图块(这是图像数据的一部分被加载到内存中) CGImageCreateWithImageInRect 使用到目的地上下文 CGContextDrawImage

看到 来自Apple的示例代码


9
2017-11-16 10:33



非常好,它不能比Apple的代码示例更具权威性,正是关于这个话题! - DarkDust


大图像不适合内存。因此将它们加载到内存中然后调整它们的大小不起作用。

要处理非常大的图像,您必须将它们平铺。已经有很多解决方案,例如,看看这是否可以解决您的问题:

https://github.com/dhoerl/PhotoScrollerNetwork

我实现了自己的自定义解决方案,但这是特定于我们的环境,我们有一个运行服务器端的图像管理器已经和我可以请求特定的大图像区块(制作服务器,它真的很酷)

平铺工作的原因是,基本上你只能将可见像素保留在内存中,并且没有那么多。当前不可见的所有切片都会被分解到磁盘高速缓存或闪存高速缓存中。


1
2017-07-04 01:30





看看Trevor Harmon的这项工作。它改善了我的应用程序的性能。我相信它也适合你。

https://github.com/coryalder/UIImage_Resize


0
2017-11-15 22:21



由于这是在已经内存的UIImage上运行,它如何避免内存问题? - DarkDust