给定一个 CIImage,将图像数据写入磁盘的最快方法是什么?

2023-11-26

我正在使用 PhotoKit 并实现了用户可以应用于其照片库中的照片的过滤器。我目前正在获取图像,应用过滤器,将编辑后的版本返回为CIImage,然后我将CIImage into NSData using UIImageJPEGRepresentation所以我可以将其写到磁盘上。虽然这效果很好,但当用户尝试编辑非常大(如 30 MB)的照片时,可能需要 30 秒以上的时间才能完成,其中 98% 的时间花在UIImageJPEGRepresentation(从 Instruments 获得的统计数据)。

如果可能的话,我正在寻找一种更有效的方法来将编辑后的照片保存到磁盘而不影响质量。

我明白UIImagePNGRepresentation可能会提高质量,但这比 JPEG 表示还要慢。

这就是我目前正在默认优先级线程上所做的事情(qos_class_utility):

func jpegRepresentationOfImage(image: CIImage) -> NSData {
    let eaglContext = EAGLContext(API: .OpenGLES2)
    let ciContext = CIContext(EAGLContext: eaglContext)

    let outputImageRef = ciContext.createCGImage(image, fromRect: image.extent())
    let uiImage = UIImage(CGImage: outputImageRef, scale: 1.0, orientation: UIImageOrientation.Up)

    return UIImageJPEGRepresentation(uiImage, 0.9) //this takes upwards of 20-30 seconds with large photos!
}

//writing out to disk:
var error: NSError?
let success = jpegData.writeToURL(contentEditingOutput.renderedContentURL, options: NSDataWritingOptions.AtomicWrite, error: &error)

尝试使用 CIContext 方法写JPEG表示(iOS 10 可用)如下,以避免 UIImage 并使写入速度更快。

extension CIImage {

    @objc func saveJPEG(_ name:String, inDirectoryURL:URL? = nil, quality:CGFloat = 1.0) -> String? {
        
        var destinationURL = inDirectoryURL
        
        if destinationURL == nil {
            destinationURL = try? FileManager.default.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        }
        
        if var destinationURL = destinationURL {
            
            destinationURL = destinationURL.appendingPathComponent(name)
            
            if let colorSpace = CGColorSpace(name: CGColorSpace.sRGB) {
                
                do {

                    let context = CIContext()

                    try context.writeJPEGRepresentation(of: self, to: destinationURL, colorSpace: colorSpace, options: [kCGImageDestinationLossyCompressionQuality as CIImageRepresentationOption : quality])
                    
                    return destinationURL.path
                    
                } catch {
                    return nil
                }
            }
        }
        
        return nil
    }
}

@objc 关键字使您能够在 Objective-C 中调用该方法,如下所示:

NSString* path = [image saveJPEG:@"image.jpg" inDirectoryURL:url quality:1.0];

对于 PNG 有类似的方法写PNG表示对于 iOS 11:

   if #available(iOS 11.0, *) {

        if let colorSpace = CGColorSpace(name: CGColorSpace.sRGB) {
                
            do {
                let format = CIFormat.RGBA8
                    
                try context.writePNGRepresentation(of: self, to: destinationURL, format: format, colorSpace: colorSpace)
                    
                return destinationURL.path
                    
            } catch {
                return nil
            }   
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

给定一个 CIImage,将图像数据写入磁盘的最快方法是什么? 的相关文章

随机推荐

  • NSURLRequest:如何处理重定向的帖子?

    我对 NSURLRequest 和伴奏 实现进行了尝试和测试 它非常适合给定 URL 的 GET 和 POST 但是 我现在想要移动 URL 的目标而不更改应用程序使用的 URL 因此我打算通过 DNS 提供商使用 Webhop 重定向 这
  • Babel.js 如何将类声明编译成 ES2015?

    我当前的任务是将 JavaScript 组件 ES5 转换为 ES6 用 Babel js 编译 在使用类和 Babel js 之前 我们进行原型设计以从其他组件获取函数 com company js ComponentA prototyp
  • libpng 1.5.10 错误:取消引用指向不完整类型的指针

    png read info png ptr info ptr png byte color type info ptr gt color type png byte bit depth info ptr gt bit depth 对于最后两
  • 在 Javascript 中反序列化 PHP 数组

    我有一个表 其中包含一系列序列化数组的行 我计划请求并将其传递给JavaScript 问题是 是否有可能unserialize使用 JavaScript 而不是 PHP 否则 我将不得不加载所有行 循环它们并反序列化它们 并将它们分配给一个
  • kubernetes - 将入口流量路由到某些路径的特定 Pod

    我有多个 Pod 可以自动扩展和缩小 我使用入口作为入口点 我需要根据某些条件 比如说路径 将外部流量路由到特定的 Pod 在发出请求时 我确信特定的 Pod 已启动 例如 假设我有域 someTest com 通常将流量路由到 pod 1
  • 如果值是由触发器生成的,如何注释 Id 列?

    我设置了 Oracle XE 10g Hibernate 3 5 JPA 2 0 有一个带有主键的简单表 由数据库触发器在插入时生成 触发器从序列中获取值 触发器 序列构造是由Oracle XE 完成的 实际的问题是 在 EntityMan
  • devtools::check() 上的包导入错误

    我有一个包 其中在描述文件中包含以下包导入 Imports lubridate assertthat R6 stringr I don t使用以下命令将它们导入到我的包的命名空间中import pkgname or importFrom p
  • 如何在不创建数组的情况下使用 NgFor 来生成矩阵 UI 模式

    我想实现 UI 矩阵模式 它应该动态生成 通过接收输入参数 它应该决定 UI 矩阵图案的尺寸 例如 9X3 元素 图案 9x3 元素 我使用 Angular2 js typescript SCSS html 模板及其外观 import Co
  • 使用 sed 或 awk 修复日期格式

    我正在尝试使用以下方法将包含表格的 HTML 转换为 csv 文件bash script 到目前为止我已经完成了以下步骤 转换为 Unix 格式 使用dos2unix 删除所有空格和制表符 使用sed s t g 删除所有空行 用sed a
  • 如何从特定矩形区域内的 pdf 文档中提取文本? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我必须从特定矩形区域内的 pdf 文档中提取文本 工作流程如下 首先将pdf转换为jpg图像 然后用户在图片顶部绘制选择矩形 然后我需要以某种方式从
  • MVP 中的模型需要上下文

    在 android 中使用 MVP 时 我需要使用模型中的活动上下文来获取所有已安装应用程序的列表 访问上下文的正确方法是什么 或者在遵循 MVP 模式的同时实现相同目的的任何替代方法是什么 以下是课程 主要活动 java public c
  • Python 函数定义中 -> 是什么意思?

    我最近在看的时候发现了一些有趣的事情Python 3 3 语法规范 funcdef def NAME parameters gt test suite Python 2 中缺少可选的 箭头 块 我在 Python 3 中找不到有关其含义的任
  • onclick按钮时如何清除编辑文本

    如何清除单击按钮时动态提供给 EditText 的数据 我该如何编写代码 我使用什么功能或方法 Try public void clear View v edittext setText Where clear被注册为布局文件中按钮的 on
  • jquery:用跨度替换输入

    我试图用包含输入值的跨度替换输入 以便能够在单击按钮时将它们切换回来 我认为这最容易分两个阶段完成 添加 span input value span 在输入前面 然后隐藏输入 唯一的问题是我在第一部分遇到了麻烦 我正在尝试类似的事情 con
  • 从视图创建表 - Oracle SQL SQL 错误:ORA-01723:不允许使用零长度列

    我需要从视图创建一个表 语句如下 CREATE TABLE NEW TABLE AS SELECT from VIEW 它给出如下错误消息 无法从视图创建表 使用 Select 语句 Error report SQL Error ORA 0
  • error_get_last() 和自定义错误处理程序

    odbc errormsg不报告错误消息odbc execute就像它应该的那样 它只是发出警告 所以我被迫编写一个 hack 来解析错误消息error get last 我在用着set error handler and error ge
  • 选项卡中的 Google 图表 - 隐藏选项卡中的图表大小和位置不正确

    我有一组两个选项卡 每个选项卡内都有一个 Google 图表 这两个图表的大小和位置应该相同 加载页面后 图表的位置就是我想要的位置 无论您最初位于哪个选项卡 然后 当您移动到另一个选项卡 最初隐藏 时 图表的位置和大小会发生变化 您可以在
  • 是否应该关闭 JPA 实体管理器?

    我有下面的方法 public Profile readUser String email EntityManager em EMF get createEntityManager return em find Profile class e
  • UIViewController 转换 - Objective-C

    I have UIViewControllersA和B 它们被分配在AppDelegate 我需要对他们应用过渡 如何在不重新分配和更换的情况下传输它们UIViews 这段代码从我的调用UIBarButtonItem in UINaviga
  • 给定一个 CIImage,将图像数据写入磁盘的最快方法是什么?

    我正在使用 PhotoKit 并实现了用户可以应用于其照片库中的照片的过滤器 我目前正在获取图像 应用过滤器 将编辑后的版本返回为CIImage 然后我将CIImage into NSData using UIImageJPEGRepres