访问 swift 中的 EXIF 数据
access EXIF data in swift
我尝试使用此示例代码访问 Exif 数据:
let fileextension = NSURL(fileURLWithPath: mDir + "/" + f).pathExtension
if fileextension == "PSD" || fileextension == "NEF" || fileextension == "3FR" || fileextension == "CR2" || fileextension == "DNG" || fileextension == "JPEG" || fileextension == "JPG" || fileextension == "PSB" || fileextension == "RAF" || fileextension == "TIF" {
let fileattr = try fileManager.attributesOfItem(atPath: mDir + "/" + f)
let filesize = fileattr[FileAttributeKey.size] as! Int64
let UrlPath = URL(fileURLWithPath: mDir + "/" + f)
let imageSource = CGImageSourceCreateWithURL(UrlPath as CFURL, nil)
let result = CGImageSourceCopyMetadataAtIndex(imageSource!, 0, nil)
let d = result as! [AnyHashable:Any]
let tiffDict = d["{TIFF}"] as! [AnyHashable:Any]
let filedate = tiffDict["DateTime"] as! Date
我有这个错误:
Could not cast value of type '__NSCFType' (0x7fff89750188) to
'NSDictionary' (0x7fff89750fe8).
但是这个示例代码可以在 playground 中运行。
有什么解释吗?
要回答实际问题 ;),看起来您调用了错误的函数来直接将其作为字典获取,而不是使用 CGImageSourceCopyMetadataAtIndex
复制元数据,而使用 CGImageSourceCopyPropertiesAtIndex
代替
if let props = CGImageSourceCopyPropertiesAtIndex(imageSource!, 0, nil) as? [String: Any],
let tiffData = props["{TIFF}"] {
print(tiffData)
}
原回答
我使用 CGImageMetadataCopyTags
将元数据提取为数组,然后使用 CGImageMetadataTagCopyName
和 CGImageMetadataTagCopyValue
将数据映射到 swift 字典中
let extensions = ["PSD", "NEF", "3FR", "CR2", "DNG", "JPEG", "JPG", "PSB", "RAF", "TIF"]
let fileManager = FileManager.default
let url = URL(fileURLWithPath: mDir + "/" + f)
var metaData = [String: Any]()
if extensions.contains(url.pathExtension) {
let imageSource = CGImageSourceCreateWithURL(url as CFURL, nil)
if let result = CGImageSourceCopyMetadataAtIndex(imageSource!, 0, nil) {
if let array = CGImageMetadataCopyTags(result) as? [CGImageMetadataTag] {
metaData = array.reduce(into: [String: Any]()) {
guard let name = CGImageMetadataTagCopyName(),
let value = CGImageMetadataTagCopyValue()
else {
return
}
[=11=][String(name)] = value
}
}
}
}
请注意,这只给出了像 "ShutterSpeedValue" 这样的标签名称,为了包括像 "exif"、"tiff"、"xmp" 这样的标签类型,我们还可以得到前缀:
guard let prefix = CGImageMetadataTagCopyPrefix(),
let name = CGImageMetadataTagCopyName(),
let value = CGImageMetadataTagCopyValue()
else { return }
[=12=]["\(prefix):\(name)"] = value
我尝试使用此示例代码访问 Exif 数据:
let fileextension = NSURL(fileURLWithPath: mDir + "/" + f).pathExtension
if fileextension == "PSD" || fileextension == "NEF" || fileextension == "3FR" || fileextension == "CR2" || fileextension == "DNG" || fileextension == "JPEG" || fileextension == "JPG" || fileextension == "PSB" || fileextension == "RAF" || fileextension == "TIF" {
let fileattr = try fileManager.attributesOfItem(atPath: mDir + "/" + f)
let filesize = fileattr[FileAttributeKey.size] as! Int64
let UrlPath = URL(fileURLWithPath: mDir + "/" + f)
let imageSource = CGImageSourceCreateWithURL(UrlPath as CFURL, nil)
let result = CGImageSourceCopyMetadataAtIndex(imageSource!, 0, nil)
let d = result as! [AnyHashable:Any]
let tiffDict = d["{TIFF}"] as! [AnyHashable:Any]
let filedate = tiffDict["DateTime"] as! Date
我有这个错误:
Could not cast value of type '__NSCFType' (0x7fff89750188) to 'NSDictionary' (0x7fff89750fe8).
但是这个示例代码可以在 playground 中运行。
有什么解释吗?
要回答实际问题 ;),看起来您调用了错误的函数来直接将其作为字典获取,而不是使用 CGImageSourceCopyMetadataAtIndex
复制元数据,而使用 CGImageSourceCopyPropertiesAtIndex
代替
if let props = CGImageSourceCopyPropertiesAtIndex(imageSource!, 0, nil) as? [String: Any],
let tiffData = props["{TIFF}"] {
print(tiffData)
}
原回答
我使用 CGImageMetadataCopyTags
将元数据提取为数组,然后使用 CGImageMetadataTagCopyName
和 CGImageMetadataTagCopyValue
将数据映射到 swift 字典中
let extensions = ["PSD", "NEF", "3FR", "CR2", "DNG", "JPEG", "JPG", "PSB", "RAF", "TIF"]
let fileManager = FileManager.default
let url = URL(fileURLWithPath: mDir + "/" + f)
var metaData = [String: Any]()
if extensions.contains(url.pathExtension) {
let imageSource = CGImageSourceCreateWithURL(url as CFURL, nil)
if let result = CGImageSourceCopyMetadataAtIndex(imageSource!, 0, nil) {
if let array = CGImageMetadataCopyTags(result) as? [CGImageMetadataTag] {
metaData = array.reduce(into: [String: Any]()) {
guard let name = CGImageMetadataTagCopyName(),
let value = CGImageMetadataTagCopyValue()
else {
return
}
[=11=][String(name)] = value
}
}
}
}
请注意,这只给出了像 "ShutterSpeedValue" 这样的标签名称,为了包括像 "exif"、"tiff"、"xmp" 这样的标签类型,我们还可以得到前缀:
guard let prefix = CGImageMetadataTagCopyPrefix(),
let name = CGImageMetadataTagCopyName(),
let value = CGImageMetadataTagCopyValue()
else { return }
[=12=]["\(prefix):\(name)"] = value