照片编辑扩展名-将图像还原为原始图像

时间:2018-10-22 12:27:25

标签: ios photosframework

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

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


在编辑扩展名上, ,该控制器的方法由“照片”应用程序的编辑会话调用,如Apple文档和您可以在网上找到的各种教程中所述。 另一方面,在容器应用程序上,

,我首先通过PHAsset类获得了UIImagePickerController实例,并直接像这样在“工作”视图控制器上手动启动编辑会话:

// '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的完成处理程序来完成编辑,则Photos框架将提示用户“还原”图像而不是“修改”图像:

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...)

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


从照片编辑扩展程序内将以前的编辑还原为图像的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

几个月后,仍然没有答案,因此我勉强采用了这种解决方法(相对于错误警报,它还是更好的选择):

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

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

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

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

  4. 从编辑输入的inputURL属性中读取未修改的图像,并将其未修改写入由PHContentEditingOutput实例的{{1} }属性。

  5. 调用renderedContentURL块,并传递编辑输出实例(通常)。

结果:图像以其原始状态保存(未应用任何效果),并且没有警报或错误发生。

缺点::图书馆资产仍处于“已编辑”状态(因为我们传递了非零的编辑输出和调整数据,因此没有其他选择),因此下次用户尝试时要从Photos.app编辑它,将显示红色的“还原”按钮:

enter image description here

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

-

更新资料

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

enter image description here

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

相关问题