2017-05-11 10 views
2

JPEG 이미지에 포함 된 메타 데이터를 수정하려고합니다. 예를 들어 현재 날짜에 DateTimeDigitized 속성으로 변경하려고 시도하고있는 이미지의 메타 데이터 일 수 있습니다.이미지 메타 데이터 수정

내 코드는 대부분 작동하는 것처럼 보이지만 set 속성은 변경되지 않고 제거됩니다. 왜 이런 일이 일어나고 있는지 확신 할 수 없습니다. 내가 잘못한 것을 누군가가 말해 줄 수 있습니까?

작업을 수행하는 데 도움이되는 프레임 워크에 대한 조언을 환영하지만 특히이 접근 방식으로 잘못하고있는 것에 관심이 있습니다.

"foo.jpg"라는 이미지가 ~/Documents/Shared Playground Data/ 경로에 저장되는 놀이터에서이 코드를 실행하고 있습니다.

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

저는 1 년 동안 EXIF ​​데이터를 수정하는 방법을 찾고있었습니다. 그래서 내가 북마크 한 질문에는 답변이 없었습니다. 하지만 오늘은 검색을했는데 이것이 돌아 왔습니다. 변경된 데이터를 실제로 저장할 수 있다고 말하지는 않았지만 어쨌든 도움이 될 수 있습니다. http://stackoverflow.com/questions/37992611/swift-how-to-modify-exif-info-in-images-taken-from-mobile-camera 실제로 작동하는지 여기에 알려주세요. – dfd

+0

@dfd이 코드는 데이터를 저장하기 위해 작동하지만 데이터 형식을 잘못 정리하여 정리했습니다. 자세한 내용은 내 [대답] (http://stackoverflow.com/a/43929720/887210)을 참조하십시오. – ColGraff

답변

2

내가 발견 이후는 데이터를 저장되지 않아 보이는 이유는 자신이 대답 해요 :

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

결과의 관련 비트

, 나는 간결의 다른 필드를 제거 이 질문처럼 다른 사람들을 도울 수 있습니다.

내 코드가 정확합니다. 유일한 문제는 날짜를 올바르게 포맷하지 못했기 때문입니다. 날짜가 올바른 형식이 아니기 때문에 프레임 워크에서 정리했습니다. 이 같은 날짜 포맷과 저장하고 제대로 표시 :

exif[ImagePropertyExifDateTimeDigitized] = Date() as CFDate 

출력은 이제 (다시에만 관련 속성 정리)입니다 :

이 라인 대신에

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

했다

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"; 
    }; 
}