【问题标题】:Photo Editing Extension - Revert Image to Original照片编辑扩展 - 将图像还原为原始图像
【发布时间】:2018-10-22 12:27:24
【问题描述】:

我正在为 iOS 开发一个照片编辑扩展程序,它捆绑在一个提供相同照片编辑功能的容器应用程序中。

为了重用代码,我有一个视图控制器类,它采用了所需的PHContentEditingController 协议,我将它子类化为既用作应用扩展的主界面,又用作容器的“工作屏幕”应用程序。


在编辑扩展上,控制器的方法由照片应用的编辑会话调用,如 Apple 文档和您可以在网络上找到的各种教程中所述。 p>

在容器应用上,另一方面,我先通过UIImagePickerController类获取一个PHAsset实例,直接启动编辑会话像这样在我的“工作”视图控制器上手动操作:

// 'work' is my view controller which adopts
// `PHContentEditingController`. 'workNavigation'
// embeds it.

let options = PHContentEditingInputRequestOptions()
options.canHandleAdjustmentData = { (adjustmentData) in
    return work.canHandle(adjustmentData)
}

asset.requestContentEditingInput(with: options, completionHandler: { [weak self] (input, options) in
    // (Called on the Main thread on iOS 10.0 and above)
    guard let this = self else {
        return
    }
    guard let editingInput = input else {
        return
    }
    work.asset = asset
    work.startContentEditing(with: editingInput, placeholderImage: editingInput.displaySizeImage!)
    this.present(workNavigation, animated: true, completion: nil)
})

当用户完成编辑,工作视图控制器会调用自己的finishContentEditing(completionHandler: 来完成会话:

self.finishContentEditing(completionHandler: {(output) in
    // nil output results in "Revert" prompt.
    // non-nil output results in "Modify" prompt. 

    let library = PHPhotoLibrary.shared()
    library.performChanges({
        let request = PHAssetChangeRequest(for: self.asset)
        request.contentEditingOutput = output

    }, completionHandler: {(didSave, error) in
        if let error = error {
            // handle error...

        } else if didSave {
            // proceed after saving...

        } else {
            // proceed after cancellation...
        }
    })
})

在编辑会话中,用户可以“清除”以前作为调整数据传递的编辑,从而有效地将图像恢复到其原始状态。 我注意到,如果我通过调用传递给finishContentEditing(completionHandler:) 的完成处理程序以nil 作为其参数(而不是有效的PHContentEditingOutput 对象)来完成编辑,照片框架将提示用户“恢复”图像而不是“修改”它:

func finishContentEditing(completionHandler: @escaping (PHContentEditingOutput?) -> Void) {

    guard let editingInput = self.editingInput, let inputURL = editingInput.fullSizeImageURL else {
        return completionHandler(nil)
    }

    if editingInput.adjustmentData != nil && hasUnsavedEdits == false {
        // We began with non-nil adjustment data but now have 
        // no outstanding edits - means REVERT:

        return completionHandler(nil)
    }

    // (...proceed with writing output to url...)

但是,这仅在从容器应用程序运行时有效。如果我尝试使用 extension 中的相同技巧(即,加载包含先前编辑的图像,请重置他们,然后点击“完成”)我收到可怕的“无法保存更改”消息...


从照片编辑扩展程序中恢复以前对图像的编辑的正确方法是什么?

【问题讨论】:

  • 我想我会通过反复试验来解决这个问题...

标签: ios photosframework


【解决方案1】:

几个月后,仍然没有答案,所以我不情愿地采用了这个解决方法(这仍然比错误警报更可取):

当用户从照片扩展 UI 中点击“完成”并且图像没有应用任何编辑(因为用户重置了以前的编辑,或者没有对全新的图像应用任何更改),请执行以下操作finishContentEditing(completionHandler:) 内部的操作:

  1. 创建完全没有可见变化的调整数据(“无效效果”)并将其存档为Data

  2. 使用上面的“空效应”数据创建一个PHAdjustmentData 实例,并正确设置formatVersionformatIdentifier

  3. 从会话开始时传递的编辑输入创建一个PHContentEditingOutput 实例(像往常一样),并设置上面创建的调整数据。

  4. 从编辑输入的inputURL属性读取未修改的图像,并将其未修改写入PHContentEditingOutput实例的renderedContentURL属性指定的url。

  5. 调用completionHandler 块,传递编辑输出实例(正常)。

结果:图像以其原始状态保存(未应用任何效果),并且不会出现警报或错误。

缺点:库资源一直处于“已编辑”状态(因为我们传递了非零的编辑输出和调整数据,没有其他选择),所以下次用户尝试要从 Photos.app 编辑它,将出现红色的“还原”按钮:

但是,选择“还原”会导致图像数据没有可见的变化(呃!),这可能会让用户感到困惑。

——

更新

我检查了内置“标记”扩展的作用:

...这与我上面的解决方法是一致的,所以我想这是可以做到的最好的。

【讨论】:

  • (这实际上是我在最后一张截图的背景中的照片)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-25
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 2012-05-03
相关资源
最近更新 更多