代码之家  ›  专栏  ›  技术社区  ›  Nicolas Miari

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

  •  0
  • Nicolas Miari  · 技术社区  · 6 年前

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

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


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

    在容器应用程序上, 另一方面,我首先得到 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 对象),照片框架将提示用户“还原”图像,而不是“修改”图像:

    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 回复  |  直到 6 年前
        1
  •  0
  •   Nicolas Miari    6 年前

    几个月后,仍然没有答案,所以我勉强接受了这个 解决方法 (这仍然比错误警报更可取):。

    当用户从照片扩展用户界面点击“完成”并且图像没有应用任何编辑时(可能是因为用户重置了以前的编辑,或者没有对新图像应用任何更改),请在 FinishContentEditing(completionHandler:)中执行以下操作:

    1. 创建相当于完全没有可见更改的调整数据(“空效果”),并将其存档为 data。

    2. 使用上面的“空效果”数据创建一个 phadjustmentdata instance,使用 formatversion formatIdentifier properly set.

    3. 从会话开始时传递的编辑输入创建一个 phContentEditingOutput instance(与往常一样),然后设置上面创建的调整数据。

    4. 从编辑输入的 inputURL->property读取未修改的图像,并将其写入 unmodified->strong>到由 phContentEditingOutput指定的URL。 Instance's renderContentURL->property.

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

    结果: The image is saved in its original state(no effects applied),and no alerts or errors occurrent.

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

    但是,选择“Revert”(恢复)会导致图像数据(duh!),这可能会让用户感到困惑。

    ε-

    更新

    我检查了内置的标记扩展功能:

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

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

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

    2. 创建一个 PHAdjustmentData 具有来自上面的“空效果”数据的实例,具有 formatVersion formatIdentifier 正确设置。

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

    4. 从中读取未修改的图像 inputURL 编辑输入的属性,并将其写入 未修改的 到由指定的URL ph内容编辑输出 实例 renderedContentURL 财产。

    5. 打电话给 completionHandler 块,通过编辑输出实例(正常)。

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

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

    enter image description here

    然而 ,选择“Revert”将导致 无可见更改 到图像数据(duh!),这可能会让用户感到困惑。

    艾尔-

    更新

    我检查了内置的标记扩展功能:

    enter image description here

    …这和我上面的解决方法是一致的,所以我想这是最好的方法。