Расширение редактирования фотографий - возврат изображения к оригиналу - PullRequest
0 голосов
/ 22 октября 2018

Я разрабатываю расширение для редактирования фотографий для iOS, включенное в контейнерное приложение, которое обеспечивает те же функции редактирования фотографий.

Для повторного использования кода у меня есть класс контроллера представления, который принимает требуемый *Протокол 1003 *, и я разделил его на подклассы для использования как в качестве основного интерфейса расширения приложения, так и в качестве «рабочего экрана» приложения контейнера.


О редактированиирасширение, методы контроллера вызываются сеансом редактирования приложения Photos, как описано в документации 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 объекта), среда Photoshop предложит пользователю «вернуться»изображение вместо «изменения» его:

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 голосов
/ 01 февраля 2019

Месяц спустя, ответа до сих пор нет, поэтому я с неохотой принял этот обходной путь (который по-прежнему предпочтительнее предупреждения об ошибке):

Когда пользователь нажимает «Готово» в расширении «Фотографии»Пользовательский интерфейс и к изображению не применяются изменения (либо потому, что пользователь сбросил предыдущие изменения, либо не применил никаких изменений к совершенно новому изображению), выполните следующие действия из finishContentEditing(completionHandler:):

  1. Создать данные уравнивания, которые вообще не имеют видимых изменений («нулевой эффект»), и заархивировать их как Data.

  2. Создать экземпляр PHAdjustmentData сданные "нулевого эффекта" сверху, с правильно установленными formatVersion и formatIdentifier.

  3. Создать экземпляр PHContentEditingOutput из входных данных редактирования, переданных в начале сеанса (как обычно), и установите данные настройки, созданные выше.

  4. Считайте неизмененное изображение из свойства inputURL ввода редактирования и запишите его unmodified вURL, указанный экземплярами PHContentEditingOutputrenderedContentURL свойство.

  5. Вызывать блок completionHandler, передавая экземпляр выходного значения редактирования (как обычно).

Результат: Изображение сохраняется в исходном состоянии (эффекты не применяются), и никаких предупреждений или ошибок не возникает.

Недостаток: Актив библиотеки остается в «отредактированном» состоянии (потому что мы передали данные вывода и корректировки, не относящиеся к нулю, другого выбора не было), поэтому в следующий раз пользователь попытается отредактировать его из Фото.приложение, красная кнопка «Вернуть» будет присутствовать:

enter image description here

Однако , выбор «вернуть» приводит к нет видимых изменений в данных изображения (дух!), что может сбить пользователя с толку.

—-

Обновление

Я проверил, что делает встроенное расширение «Разметка»:

enter image description here

... и это согласуется с моим обходным решением выше, поэтому я думаю, что это лучшее, что можно сделать.

...