在 iOS 4.0 上使用大图像时应用程序崩溃
Posted
技术标签:
【中文标题】在 iOS 4.0 上使用大图像时应用程序崩溃【英文标题】:App Crashing when using large images on iOS 4.0 【发布时间】:2011-04-10 10:00:39 【问题描述】:我在滚动视图上显示大图像时遇到了问题,图像大小为 2,4 - 4,7 MB。它在 3GS 和模拟器上运行良好。但每当我尝试在 3G 或 iPod Touch 2G 上运行时,它就会崩溃。
我在网上搜索并找到了“imageNamed is evil”的文章。好的,我将所有图像调用更改为 imageWithContentsOfFile: 但它仍然崩溃,我看到的唯一不同是现在图像在我离开视图后被释放就好了。但是内存使用率还是很高的。
这是 Instruments 的屏幕截图。 第一个高峰是我在启动时显示的视频,然后tableview显示了很多图像,直到那时没有问题。
当我输入 1.1mb - 2576 x 1000 图片时
当我输入一张 4.8mb - 7822 x 1000 的图片时
顺便说一下,该应用在 ios 4 和 3.1.2 上进行了测试
你有什么建议吗?因为这个问题快把我逼疯了。
非常感谢!
【问题讨论】:
我有一个类似的问题:三个 UIImageViews 并排在一个 UIScollView 中。当图像是 JPG(缩放为 1200x1600)时,内存使用量很疯狂:像你的例子一样跳到 30Mb+。 但是,如果我改用 PNG 图像,则内存使用率会很低(并且不会崩溃)。不幸的是,PNG 的大小是在设备上下载和存储的三倍 :-( 【参考方案1】:我最近在 3G 上测试应用时遇到了同样的问题。我最终缩小了任何大于最大像素数的图像(我发现 200 万像素似乎在我的 3G 上可靠地工作,但 hotpaw2 的回答似乎表明 100 万像素可能是更安全的选择)。
UIImage *image = // ...;
if (image.size.width * image.size.height > MAX_PIXELS)
// calculate the scaling factor that will reduce the image size to MAX_PIXELS
float actualHeight = image.size.height;
float actualWidth = image.size.width;
float scale = sqrt(image.size.width * image.size.height / MAX_PIXELS);
// resize the image
CGRect rect = CGRectMake(0.0, 0.0, floorf(actualWidth / scale), floorf(actualHeight / scale));
UIGraphicsBeginImageContext(rect.size);
[image drawInRect:rect];
UIImage *imageToDraw = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// imageToDraw is a scaled version of image that preserves the aspect ratio
Apple 还提供了一个开发照片库应用程序的示例,该应用程序使用 CATiledLayer 来平铺非常大的图像。他们的示例使用已预先切成适当大小的图块的图像。可以在您的 iOS 应用程序中动态地将图像分割成图块,但在设备上这样做非常慢。查看今年 WWDC 的第 104 场会议,了解 PhotoScroller 示例。
【讨论】:
非常感谢,我刚刚查看了您说的照片库。我设法在我的 iPhone 上的 Safari 上渲染了 4mb 图像,现在我要做的是放置一个 web 视图而不是滚动视图,因为我认为 Safari 使用在本机照片库中找到的相同算法。 手指交叉 我也遇到过大图像的问题。目前,我将图像大小调整为 1024x768,因为这些尺寸足以满足我的应用程序。性能提高了,从那以后我没有遇到任何崩溃。 太棒了!非常感谢,我正在以另一种方式缩放图像,但它无法像您的代码一样处理大图像。【参考方案2】:iPhone 3G 和 iPod Touch 1G/2G 中的 GPU 只能容纳 1k x 1k 纹理,这似乎也用于 2D 图像渲染。任何更大的东西都需要平铺以适应硬件图形渲染器。
3GS 和更新版本具有不同的 GPU,可以支持更大的纹理,从而支持图像。
【讨论】:
我想知道iphone原生相册是怎么做的,你觉得是这样吗? 你能提供任何代码来将图像平铺到其他部分吗? 如果您可以访问 Apple 的开发者网站,请在此处登录:developer.apple.com/videos/wwdc/2010 并通过 iTunes 下载示例代码和会话视频 104(感谢GreginYEG
提及此会话)。
对于那些寻找会话 104 的人来说,它被称为“设计带有滚动视图的应用程序”。【参考方案3】:
我最终使用了 UIWebView,我不得不使用更小的(以 MB 为单位,而不是尺寸)图像,但它正在运行,唯一的问题是我无法缩放...使用 scalePageToFit 我可以缩放但图像适合水平而不是垂直,那个sux。
我会努力更新这个问题。
如果有人遇到这个问题,我建议使用 webview 或可以更好地处理内存的 three20 图像查看器的适配器版本。
【讨论】:
以上是关于在 iOS 4.0 上使用大图像时应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章