0

我必须将 50 个正方形图像(600 像素 x 600 像素)分成 9 个相同大小(200x200)的正方形部分。要获得每个部分,我使用方法:

-(UIImage *)getSubImageFrom:(UIImage *)img WithRect:(CGRect)rect
{
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();

// translated rectangle for drawing sub image
CGRect drawRect = CGRectMake(-rect.origin.x, -rect.origin.y, img.size.width, img.size.height);

// clip to the bounds of the image context
// not strictly necessary as it will get clipped anyway?
CGContextClipToRect(context, CGRectMake(0, 0, rect.size.width, rect.size.height));

// draw image
[img drawInRect:drawRect];

// grab image
UIImage* subImage = UIGraphicsGetImageFromCurrentImageContext();

CGContextRelease(context);

return subImage;
}

它对我来说已经足够快了……从今天开始。我曾经使用 [UIImage imageNamed:] 方法加载图像。在应用程序收到内存警告之前,此方法不会自动释放内存......这对我来说是不可接受的。

所以我开始使用 [UIImage imageWithContentsOfFile]。内存分配问题消失了......不幸的是,我的裁剪方法 (-(UIImage *)getSubImageFrom:(UIImage *)img WithRect:(CGRect)rect) 开始工作慢 20 倍!自从我开始寻找解决方案以来已经有几个小时了……没有结果。希望您能够帮助我。

此致!

PS。我尝试使用这个问题的提示CGContextDrawImage is EXTREMELY after large UIImage draw into it,没有任何结果。

4

1 回答 1

0

这就是我们所说的“权衡”。您抱怨+[UIImage imageNamed:]使事情变得更快但使用更多内存,并且+[UIImage imageWithContentsOfFile:]速度很慢但不使用太多内存。后者速度慢的原因是每次调用+[UIImage imageWithContentsOfFile:]它时都必须从“磁盘”读取和解码图像,这需要时间(正如您所了解的那样,这是一段不平凡的时间)。当您使用+[UIImage imageNamed:]它时,它会被读取和解码一次,然后读取/解码操作的结果会保存在内存中,直到出现内存警告。这意味着对该图像的后续访问(在内存警告之前)将很快。

听起来不错的方法是将图像缓存在可以控制其生命周期的缓存中。NSCache将是显而易见的选择,因为它也被挂接到系统内存挂钩中,但您可以使用-removeObjectForKey:

另一种方法可能是创建一次子图像并将它们写入磁盘(寻找NSCachesDirectory放置这些东西的好地方)。这将消除多次执行此(相对昂贵)子集操作的需要,并且较小的图像(假设您不需要一次全部)可能比较大的图像更快地从磁盘加载。

扮演魔鬼的拥护者一分钟:如果 UIImage 在内存警告出现时做正确的事情,你为什么关心它使用内存?这种内存使用是否真的导致您的应用程序被杀死?(我从经验中知道内存警告不是互锁的——即在你的进程被杀死之前你不一定有足够的时间来减少你的消耗——但你真的有这个问题吗?换句话说,你的减少内存消耗的努力可能被视为过早优化?

于 2013-08-01T12:14:17.350 回答