0

我目前正在尝试在滚动视图中加载一个大(16mb).jpg 文件的地图图像,以便您可以放大和缩小。

当我在模拟器中启动应用程序时,一切运行良好且流畅。但是,一旦我在我的测试设备(iPod 4.1、iOS 6.0)上运行它,应用程序就会显示启动图像,然后它就崩溃了,根本没有错误消息。

这就是代码当前的样子。

myImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"map.jpg"]];

myScrollView=[[UIScrollView alloc]initWithFrame:CGRectMake(15,120,290,365)];
myScrollView.showsVerticalScrollIndicator=YES;
myScrollView.scrollEnabled=YES;
myScrollView.maximumZoomScale = 10.0;
myScrollView.minimumZoomScale = [myScrollView frame].size.width / myImage.frame.size.width;
myScrollView.clipsToBounds = YES;
myScrollView.bounces = NO;

myScrollView.showsHorizontalScrollIndicator = NO;
myScrollView.showsVerticalScrollIndicator = NO;

[self.view addSubview:whiteFrame];
[self.view addSubview:myScrollView];

myScrollView.contentSize = CGSizeMake(myImage.frame.size.width,myImage.frame.size.height);
myScrollView.delegate = self;
myScrollView.zoomScale = [myScrollView frame].size.width / myImage.frame.size.width;

[myScrollView addSubview:myImage];

任何帮助是极大的赞赏。

编辑:

我在文档中找到了这个

如果您有一个非常大的图像,或者正在通过网络加载图像数据,您可能需要创建一个增量图像源,以便您可以在累积图像数据时绘制它。您需要执行以下任务以从 CFData 对象增量加载图像:

  1. 创建 CFData 对象用于累积图像数据。

  2. 通过调用函数 CGImageSourceCreateIncremental 创建增量图像源。

  3. 将图像数据添加到 CFData 对象。

  4. 调用函数 CGImageSourceUpdateData,传递 CFData 对象和一个布尔值(bool 数据类型),该值指定数据参数是包含整个图像,还是仅包含部分图像数据。在任何情况下,data 参数都必须包含到该点为止累积的所有图像文件数据。

  5. 如果你积累了足够多的图片数据,调用CGImageSourceCreateImageAtIndex创建图片,绘制部分图片,然后释放。

  6. 通过调用函数 CGImageSourceGetStatusAtIndex 检查您是否拥有图像的所有数据。如果图像完整,则此函数返回 kCGImageStatusComplete。如果图像不完整,请重复步骤 3 和 4,直到完成。

  7. 释放增量镜像源。

有谁知道一个示例代码?

4

4 回答 4

1

16 MB 的图像太大,您的 iPod 无法处理。该应用程序崩溃,因为它直接加载图像,并要求过多的内存,系统不得不杀死它。

您应该为您的应用程序创建一个较小版本的图像,无论是画布大小还是图像质量。

您也可以改为增量加载图像。

当您在模拟器上进行测试时,它可以完全访问您计算机上的大量内存。远远超过 iPod 4 可用的 256MB(没有 iPod 4.1 之类的东西)。

于 2013-10-20T00:51:04.337 回答
1

一个 16mb 的 jpg 在未压缩时会占用相当大的内存。您的应用程序可能正在崩溃,因为它使用了太多内存。您可以通过重现崩溃并在 Xcode 管理器中检查设备的控制台日志来检查这一点。

您将需要:

  1. 在您的设计允许的范围内尽可能减少图像的尺寸,以大大减少内存使用量。例如,如果永远不会以全分辨率显示,则没有理由拥有 16mb 的 jpg。

  2. 将图像分割成图块,仅加载当前显示在屏幕和周围区域的图块。然后在用户滚动时加载其他图块。这就是地图应用程序能够在不耗尽 RAM 的情况下显示超大图像的方式。

请记住,还要在 RAM 最少的受支持设备上测试您的应用程序。这些设备可能会比最新设备更快地杀死您的应用程序。

于 2013-10-20T00:49:08.957 回答
0

我希望您不会在应用启动时加载此图像。应用程序启动应该尽可能轻。如果启动时间超过 20 秒,则 iOS 会自行终止应用程序。在模拟器上资源要大得多,您可能看不到与设备类似的行为。您可能还想使用延迟加载技术先加载较轻的图像,然后仅在缩放、平移等需要时才加载较重的图像。

话虽如此,[UIImage imageNamed] 的一个重要方面是它缓存了所有以这种方式加载的图像并且它们永远不会被卸载,即使你释放了创建的 UIImage!这在某些情况下很好(例如 UITableView 单元格中的小图像),但在其他情况下不好(例如大图像)。

解决方案是使用 [UIImage imageWithData] ,它不执行此缓存,并且在 UIImage 被释放时卸载数据。

此问题的另一个解决方案包括加载图像的缩放版本 (*1),或者您可以选择在 CATiledLayer(*2) 的帮助下以全分辨率显示它。

  1. [UIImage imageWithCGImage:scale:orientation:];
  2. CATiledLayer 示例
于 2013-10-20T00:49:41.507 回答