2017-05-11 101 views
2

我試圖修改包含在JPEG圖像中的元數據。它可以是圖像中的任何元數據,在我的示例中,我試圖將DateTimeDigitized屬性更改爲當前日期。修改圖像元數據

我的代碼似乎主要工作,但set屬性被刪除,而不是改變。我不確定爲什麼會發生這種情況,誰能告訴我我做錯了什麼?

我會歡迎任何有助於執行任務的框架建議,但是我特別關心我在這種方法中做錯了什麼。

我在Playground上運行此代碼,其中名爲「foo.jpg」的圖像存儲在路徑~/Documents/Shared Playground Data/中。

import Foundation 
import ImageIO   // CGImage functions 
import PlaygroundSupport 

let ImagePropertyExifDictionary = kCGImagePropertyExifDictionary as String 
let ImagePropertyExifDateTimeDigitized = kCGImagePropertyExifDateTimeDigitized as String 

func updateEXIFDateDigitized() { 
    // Create URL for source and destination 
    let sourceURL = playgroundSharedDataDirectory.appendingPathComponent("foo.jpg") as CFURL 
    let destinationURL = playgroundSharedDataDirectory.appendingPathComponent("bar.jpg") as CFURL 

    // Read source and get properties 
    guard 
    let sourceRef = CGImageSourceCreateWithURL(sourceURL, nil), 
    var metadata = CGImageSourceCopyPropertiesAtIndex(sourceRef, 0, nil) as? [String:Any] else { return } 

    print("unmodified properties", metadata, separator:"\n") 

    // Modify EXIF DateTimeDigitized property 
    guard var exif = metadata[ImagePropertyExifDictionary] as? [String:Any] else { return } 

    exif[ImagePropertyExifDateTimeDigitized] = Date() as CFDate 
    metadata[ImagePropertyExifDictionary] = exif as CFDictionary 
    print("", "modified properties", metadata, separator:"\n") 

    // Set up destination 
    guard let destinationRef = CGImageDestinationCreateWithURL(destinationURL, "public.jpeg" as CFString, 1, nil) else { return } 

    // Add image from source to destination with new properties 
    CGImageDestinationAddImageFromSource(destinationRef, sourceRef, 0, metadata as CFDictionary) 

    // Save destination 
    guard CGImageDestinationFinalize(destinationRef) else { return } 

    guard 
    let sourceRef2 = CGImageSourceCreateWithURL(destinationURL, nil), 
    let metadata2 = CGImageSourceCopyPropertiesAtIndex(sourceRef2, 0, nil) else { return } 

    print("", "saved properties", metadata2, separator:"\n") 
} 

updateEXIFDateDigitized() 

結果中的相關內容,我刪除了簡潔其他字段:

unmodified properties 
{ 
    "{Exif}" =  { 
    DateTimeDigitized = "2007:07:31 17:42:01"; 
    DateTimeOriginal = "2007:07:31 17:42:01"; 
    }; 
} 

modified properties 
{ 
    "{Exif}" =  { 
    DateTimeDigitized = "2017-05-11 15:45:38 +0000"; 
    DateTimeOriginal = "2007:07:31 17:42:01"; 
    }; 
} 

saved properties 
{ 
    "{Exif}" =  { 
    DateTimeOriginal = "2007:07:31 17:42:01"; 
    }; 
} 
+0

我一直在尋找方法來修改EXIF數據一年,現在,關閉。我在SO上收藏的問題都沒有答案。但是今天我做了一次搜索,然後又回來了 - 它並沒有說明你實際上可以保存已更改的數據,但它可以幫助你。 http://stackoverflow.com/questions/37992611/swift-how-to-modify-exif-info-in-images-taken-from-mobile-camera讓我知道這裏,如果它真的有效。 – dfd

+0

@dfd此代碼確實能夠保存數據,我的數據格式錯誤,因此它正在被修剪。請參閱我的[answer](http://stackoverflow.com/a/43929720/887210)瞭解更多信息。 – ColGraff

回答

2

我回答這個自己,因爲我發現,爲什麼它不保存數據,它看起來喜歡這個問題可以幫助別人。

我的代碼是正確的,唯一的問題是我沒有正確格式化日期。由於日期不是正確的格式,它正在被框架修剪。我此格式的日期和它保存和正確顯示:

let formatter = DateFormatter() 
formatter.dateFormat = "yyyy:MM:dd HH:mm:ss" 
exif[ImagePropertyExifDateTimeDigitized] = formatter.string(from: Date()) 

這已經到位行:

exif[ImagePropertyExifDateTimeDigitized] = Date() as CFDate 

輸出現在(再次修剪到只有相關屬性):

unmodified properties 
    { 
    "{Exif}" =  { 
     DateTimeDigitized = "2007:07:31 17:42:01"; 
     DateTimeOriginal = "2007:07:31 17:42:01"; 
    }; 
} 

modified properties 
    { 
    "{Exif}" =  { 
     DateTimeDigitized = "2017:05:12 01:04:14"; 
     DateTimeOriginal = "2007:07:31 17:42:01"; 
    }; 
} 

saved properties 
    { 
    "{Exif}" =  { 
     DateTimeDigitized = "2017:05:12 01:04:14"; 
     DateTimeOriginal = "2007:07:31 17:42:01"; 
    }; 
}