如何在运行时正确压缩 UIImages

Posted

技术标签:

【中文标题】如何在运行时正确压缩 UIImages【英文标题】:How To Properly Compress UIImages At Runtime 【发布时间】:2014-10-30 18:22:10 【问题描述】:

我需要加载 4 张图像以进行同时编辑。当我从用户库中加载它们时,内存超过 500mb 并崩溃。

这是在我进行任何压缩尝试之前来自原始分配转储的日志:

代码:

var pickedImage = UIImage(data: imageData)

仪器:

我已经阅读了几篇关于压缩 UIImages 的文章。我已经尝试减少 UIImage:

新代码:

var pickedImage = UIImage(data: imageData, scale:0.1)

仪器:

减少 UIImage 的比例没有效果?!很奇怪。

所以现在我尝试创建基于完整 UIImage 的 JPEG 压缩

新代码:

var pickedImage = UIImage(data: imageData)
var compressedData:NSData = UIImageJPEGRepresentation(pickedImage,0)
var compressedImage:UIImage = UIImage(data: compressedData)!//this is now used to display

仪器:

现在,我怀疑是因为我正在转换它仍在加载的图像。由于这一切都发生在 PHImageManager 的回调中,我需要一种从 NSData 创建压缩 UIImage 的方法,但是将比例设置为 0.1 没有任何作用。

因此,任何关于如何直接从 NSData 压缩此 UIImage 的建议都可以挽救生命!!!

谢谢

【问题讨论】:

你试过用link吗? 是的,那是老派,但谢谢(它矫枉过正)。我确实想出了另一个解决方案,我明天可以发布。 【参考方案1】:

在处理图像之前,我最终对缩小尺寸进行了硬编码。代码如下:

PHImageManager.defaultManager().requestImageForAsset(asset, targetSize:CGSizeMake(CGFloat(asset.pixelWidth), CGFloat(asset.pixelHeight)), contentMode: .AspectFill, options: options)

  result, info in
  var minRatio:CGFloat = 1
  //Reduce file size so take 1/2 UIScreen.mainScreen().bounds.width/2 || CGFloat(asset.pixelHeight) > UIScreen.mainScreen().bounds.height/2)
  
    minRatio = min((UIScreen.mainScreen().bounds.width/2)/(CGFloat(asset.pixelWidth)), ((UIScreen.mainScreen().bounds.height/2)/CGFloat(asset.pixelHeight)))
  

  var size:CGSize = CGSizeMake((CGFloat(asset.pixelWidth)*minRatio),(CGFloat(asset.pixelHeight)*minRatio))
  UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
  result.drawInRect(CGRectMake(0, 0, size.width, size.height))
  var final = UIGraphicsGetImageFromCurrentImageContext()
  var image = iImage(uiimage: final)

【讨论】:

我在 Objective-C 中遇到了同样的问题。这是我的问题链接==>***.com/questions/36034703/…。请帮我解决问题。【参考方案2】:

您遇到崩溃并看到如此高的内存使用率的原因是您错过了对UIGraphicsEndImageContext(); 的调用——因此您正在疯狂地泄漏内存。

每次致电UIGraphicsBeginImageContextWithOptions,请确保您已致电UIGraphicsEndImageContext (after UIGraphicsGetImage*)

另外,您应该使用 @autorelease 进行包装(我假设您使用的是 ARC),否则如果您正在快速处理图像,您仍然会出现内存不足的崩溃。

这样做:

@autorelease 
  UIGraphicsBeginImageContextWithOptions(...);
  ..
  something = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();

【讨论】:

以上是关于如何在运行时正确压缩 UIImages的主要内容,如果未能解决你的问题,请参考以下文章

如何解决UIImages无法在模拟器或iPhone的Xcode中不显示的问题

使用 curl 时如何正确处理压缩页面?

保留加载的 UIImages 的 alpha 问题 - 如何避免在导入时丢弃 alpha 值?

如何在 xCode 中保存 UIimages 数组(swift)

如何将 UIImages 和 NSArrays 存储在 CoreData 文件中?使用啥属性类型?

如何对 UIImages 数组进行排序?