旋转共享扩展中的图像

2023-12-28

我有这个扩展,它在应用程序目标中运行完美,但在尝试旋转相机上捕获的图像时在共享扩展中崩溃。如何旋转共享扩展中的图像?或者也许可以从照片库中加载已经处于正确方向的图像。

extension UIImage {

    func fixOrientation() -> UIImage {
        switch imageOrientation {
        case .up:
            return self
        default:
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
            draw(in: CGRect(origin: .zero, size: size)) //Thread 1: EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit=120 MB, unused=0x0)
            let result = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return result!
        }
    }
}


崩溃截图:


首先很明显你有内存崩溃。根据应用程序扩展编程指南 https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionCreation.html:

运行应用程序扩展的内存限制明显低于对前台应用程序施加的内存限制。在这两个平台上,系统可能会主动终止扩展,因为用户希望返回到主机应用程序中的主要目标。

从错误中可以明显看出,您超过了 120 mb。但您可能想知道是什么占用了这么多内存。

根据优化图像 乔丹·摩根 编剧 https://www.swiftjectivec.com/optimizing-images/:

iOS 本质上是根据图像的尺寸来获取内存占用的,而实际文件大小与之关系不大。

因此,如果我们计算尺寸或 4032 x 3024 照片,它将是... 4 位颜色为 46mb,8 位颜色为 79mb。相当大,但还不到极限......

事情是 - 你有two您的图像的副本。一张是原始的,第二张是旋转的。

要解决此问题,您只需将旋转图像加载到内存中,而不加载原始图像。这可以通过以下方式完成图像I/O框架 https://developer.apple.com/documentation/imageio:

extension UIImage {
    static func imageWithFixedOrientation(at url: URL) -> UIImage? {
        guard let imageSource = CGImageSourceCreateWithURL(url as CFURL, nil) else { return nil }

        guard let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? Dictionary<CFString, Any> else { return nil }

        guard
            let width = imageProperties[kCGImagePropertyPixelWidth] as? CGFloat,
            let height = imageProperties[kCGImagePropertyPixelHeight] as? CGFloat
            else { return nil }

        let options: [NSString: Any] = [
            kCGImageSourceThumbnailMaxPixelSize: max(width, height),
            kCGImageSourceCreateThumbnailFromImageAlways: true,
            kCGImageSourceCreateThumbnailWithTransform: true
        ]

        guard let cgImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options as CFDictionary) else { return nil }

        return UIImage(cgImage: cgImage)
    }
}

在示例应用程序中:

extension ViewController: UIImagePickerControllerDelegate & UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        picker.dismiss(animated: true)
        guard let url = info[.imageURL] as? URL else { return }

        let image = UIImage.imageWithFixedOrientation(at: url)
    }
}

它将内存峰值从 180+mb 减少到仅 80mb。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

旋转共享扩展中的图像 的相关文章

随机推荐

  • 如何在 C# 中将 SID 转换为帐户名

    我有一个 C 应用程序 可以扫描目录并收集一些信息 我想显示每个文件的帐户名 我可以通过获取 FileInfo 对象的 SID 在本地系统上执行此操作 然后执行以下操作 string GetNameFromSID SecurityIdent
  • C++ 相当于 Python __getattr__(self, name)

    我喜欢 Python 的原因之一是它的方式自定义属性访问 https docs python org 2 reference datamodel html customizing attribute access class Foo obj
  • 在Prolog中查找最大子列表

    我是 Prolog 新手 正在尝试解决以下问题的实例最大子数组问题 https en wikipedia org wiki Maximum subarray problem 我有以下相当优雅的 C 代码 int maxSubArray ve
  • 带阴影的 UIView

    我试图在一个简单的 UIView 对象周围创建一个阴影 该对象添加到 UIViewController 视图的顶部 这样做最直接的方法是什么 首先 请务必导入 Quartz Core 库 import
  • Foundation 可以告诉我 Objective-C 方法是否需要特殊的结构返回吗?

    据我了解 背景 Objective C 方法调用基本上是带有两个隐藏参数 接收器和选择器 的 C 函数调用 Objective C 运行时包含一个名为 objc msgSend 的函数 允许以这种方式调用方法 不幸的是 当函数返回结构时 可
  • 为 OpenCL 设置 Visual Studio 2010 的正确方法

    设置 VisualStuio 2010 处理 cl 文件的正确方法是什么 我在工具 文本编辑器 文件扩展名下添加了 cl 并将 usertype dat 复制到 common7 ide 文件夹中 但 VS 为 float4 或 cross
  • 如何在登录后正确注销 Java EE 6 Web 应用程序

    一个非常简单的要求 登录 Web J2EE 6 应用程序后 如何让用户再次注销 我见过的大多数 全部 书籍和教程都展示了如何向其应用程序添加登录 登录错误页面 并使用 j security check 方法演示安全主体 角色 领域等的使用
  • 处理 SQL 连接

    我有一个连接到数据库并检索数据表的 SQL 类 我知道 SqlConnection 必须在完成后释放 我知道这可以使用using块 但是也可以接受Dispose 在这个类的析构函数中调用 这是我的代码 public class SQLEng
  • 使用 Visual Studio 2010 时出现 System.OutOfMemoryException

    当我的笔记本电脑中确实有很多未使用的内存时 我收到了名为 system outofmemory exception 的非常烦人的消息 除非我关闭并重新打开解决方案 否则它不会让我继续我的工作 是否有任何配置或服务包可以解决该问题 Thank
  • 编辑后保留文本的突出显示颜色

    删除前面一行的内容后 无法保留我在 RichTextBox 中设置的文本上的突出显示效果 无论我从控件中删除多少文本 它总是会删除我设置为已包含在其中的文本的自定义选择颜色和选择背景颜色 我的删除方法的代码 private void btn
  • asdf erlang 在 macOS 上编译失败

    我正在尝试通过 asdf 在 macOS 11 3 1 上安装 erlang 22 3 4 18 erlang 的 asdf 插件 https github com asdf vm asdf erlang OSX 特定的说明说要安装auto
  • NSCoding 和 Codable 可以共存吗?

    在测试新的 Codable 如何与 NSCoding 交互时 我整理了一个游乐场测试 涉及使用包含 Codable 结构的类的 NSCoding 到惠特 struct Unward Codable var id Int var job St
  • django python 排序错误

    出现以下错误的原因是什么 当我尝试使用以下内容进行过滤时 if MyObject objects filter location aDictionary address 其中位置定义为 location models CharField m
  • 在 Postgres 中通过未知键从 jsonb 获取元素

    我有以下数据结构 proccess1 error error1 description nextRetryAt 2018 02 22T07 39 00 325Z attemptsMade 148 firstFailedAt 2018 02
  • 在路径中绘制不同颜色的形状(HTML5 Canvas / Javascript)

    我正在尝试绘制多个填充不同颜色的圆弧 draw ctx beginPath ctx fillStyle black ctx arc 30 30 20 0 Math PI 2 true ctx fill ctx fillStyle red c
  • std::iterator、指针和 VC++ 警告 C4996

    int arr int malloc 100 sizeof int int arr copy int malloc 100 sizeof int srand 123456789L for int i 0 i lt 100 i arr i r
  • 如何添加一个链接,将事件从 Safari 添加到您的 iPhone 日历?

    这看起来应该很简单 但经过几个小时的谷歌搜索后我还没有弄清楚 我知道我可以使用 ICS 文件添加 iCal 链接 但这在 iPhone 上不起作用 顺便说一句 当我说 iPhone 时 我希望它也能在触摸屏上运行 有人有这样的运气吗 您可以
  • Swift Date:如何判断一个月是否可以有闰日?

    我正在构建一个日历视图 我希望与年份无关 只需列出一个月内可能发生的所有可能日期 IE 显示日历中的最大天数 例如 2 月 29 日 从这个答案 https stackoverflow com questions 41318604 is t
  • jquery .off 似乎不起作用

    所以我会简短地说 jquery off 不会禁用我设置的监听 on html span lol span
  • 旋转共享扩展中的图像

    我有这个扩展 它在应用程序目标中运行完美 但在尝试旋转相机上捕获的图像时在共享扩展中崩溃 如何旋转共享扩展中的图像 或者也许可以从照片库中加载已经处于正确方向的图像 extension UIImage func fixOrientation