编辑照片元数据和PHAdjustmentData

时间:2018-01-15 00:40:44

标签: ios swift exif phphotolibrary

以下功能加载照片,编辑附加到其上的exif元数据并将其保存回来。该功能似乎只适用于已经附加了PHAdjustmentData的照片,即之前已使用其他应用程序编辑过的照片。如果照片尚未编辑,则在performChanges()块中失败并打印

Failed to save. Error: Optional(Error Domain=NSCocoaErrorDomain Code=-1 "(null)"). 

为什么在这种情况下会失败?浏览Stack Overflow我已经看到了这个问题的许多其他版本,但似乎没有一个得到解决。我知道如果保存的图像是PNG但我的原始图像是JPEG,则失败,因此保存的图像也是JPEG。

func editPhotoProperties(_ asset: PHAsset) {

    let options = PHContentEditingInputRequestOptions()
    options.canHandleAdjustmentData = { data in
            return false
    }
    asset.requestContentEditingInput(with: options) { input, info in
        if let input = input {
            let adjustmentData = PHAdjustmentData(formatIdentifier:"viewfinder", formatVersion:"1.0", data:"viewfinder".data(using:.utf8)!)
            let output = PHContentEditingOutput(contentEditingInput:input)
            output.adjustmentData = adjustmentData

            do {
                let imageData = try Data(contentsOf:input.fullSizeImageURL!)
            } catch {
                print("Failed to load data")
                return
            }

            let properties = getImageDataProperties(imageData)!
            let properties2 = properties.mutableCopy() as! NSMutableDictionary
            // edit properties2
            ...
            let newImageData = addImageProperties(imageData: imageData, properties: properties2)

            do {
                try newImageData!.write(to: output.renderedContentURL, options: .atomic)
            } catch {
                print("Failed to write to disk")
                return
            }           
            PHPhotoLibrary.shared().performChanges({
                let changeRequest = PHAssetChangeRequest(for:asset)
                changeRequest.contentEditingOutput = output
            }) { success, error in
                if !success {
                    print("Failed to save. Error: \(String(describing:error))")
                }
            }
        }
    }
}

func getImageDataProperties(_ data: Data) -> NSDictionary? {
    if let imageSource = CGImageSourceCreateWithData(data as CFData, nil) {
        if let dictionary = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) {
            return dictionary
        }
    }
    return nil
}

// add image properties (exif, gps etc) to image
func addImageProperties(imageData: Data, properties: NSDictionary?) -> Data? {

    // create an imagesourceref
    if let source = CGImageSourceCreateWithData(imageData as CFData, nil) {
        // this is of type image
        if let uti = CGImageSourceGetType(source) {

            // create a new data object and write the new image into it
            let destinationData = NSMutableData()
            if let destination = CGImageDestinationCreateWithData(destinationData, uti, 1, nil) {

                // add the image contained in the image source to the destination, overidding the old metadata with our modified metadata
                CGImageDestinationAddImageFromSource(destination, source, 0, properties)
                if CGImageDestinationFinalize(destination) == false {
                    return nil
                }
                return destinationData as Data
            }
        }
    }
    return nil
}

0 个答案:

没有答案