信息:使用Swift和CGImageSourceCreateWithURL函数。
我正在尝试从网址加载文件,然后编辑包含该特定照片中所有数据的字典。
这是.swift文件中的代码。
let url = NSURL(string: "http://jwphotographic.co.uk/Images/1.jpg")
let imageSource = CGImageSourceCreateWithURL(url, nil)
let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as Dictionary
println(imageProperties)
//this is an example
let aperture = imageProperties[kCGImagePropertyGPSLatitude] as! NSNumber!
/*
//these are all being defined as nil
//Load the ones from the exif data of the file
let lensUsed = imageProperties[kCGImagePropertyExifFocalLength]
let aperture = imageProperties[kCGImagePropertyExifApertureValue] as!
let isoSpeed = imageProperties[kCGImagePropertyExifISOSpeedRatings] as! NSNumber
let latitude = imageProperties[kCGImagePropertyGPSLatitude] as! NSNumber
let longitude = imageProperties[kCGImagePropertyGPSLongitude] as! NSNumber
let shutterSpeed = imageProperties[kCGImagePropertyExifShutterSpeedValue] as! NSNumber
let cameraName = imageProperties[kCGImagePropertyExifBodySerialNumber] as! NSNumber
*/
println(aperture)
即使图像属性打印出预期的所有数据,也不管我从imageProperties字典中提取的内容是什么 - 它总是返回为null - 例如' aperture'在示例中。 imageProperties打印为;
[{TIFF}: {
Artist = JOHN;
Copyright = "johnrwatson0@gmail.com";
DateTime = "2015:07:31 21:07:05";
Make = Canon;
Model = "Canon EOS 7D Mark II";
ResolutionUnit = 2;
Software = "Adobe Photoshop Lightroom 6.0 (Macintosh)";
XResolution = 72;
YResolution = 72;
}, {IPTC}: {
Byline = (
JOHN
);
CopyrightNotice = etc.. etc..
我做了大量的研究和测试,我根本无法弄清楚我在访问这本词典中的元素时做错了什么 - 有人能给我一个例子,我将如何将变量设置为&# 34;型号"字典里面的元素?
答案 0 :(得分:12)
在Swift 3.0中,我找到了以下解决方案
let url = NSURL(string: "http://jwphotographic.co.uk/Images/1.jpg")
let imageSource = CGImageSourceCreateWithURL(url, nil)
let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as Dictionary?
let exifDict = imageProperties?[kCGImagePropertyExifDictionary]
现在您可以通过例如
访问exif-Tagslet dateTimeOriginal = exifDict?[kCGImagePropertyExifDateTimeOriginal]
Swift.print("dateTimeOriginal: \(dateTimeOriginal)")
您将获得可选值,如果有值或零,则必须进行测试。有关可用属性常量的列表,请查看apple documentation。
答案 1 :(得分:8)
要获取Exif参数,请执行以下操作:
let filePath_ = "file:///Users/pfernandes/Documents/softwareDevelopment/PhotoLine/TestData/IMG_1243.JPG"
let fileURL = NSURL(string:filePath_)
let myImage = CGImageSourceCreateWithURL(fileURL!,nil)
let imageDict = CGImageSourceCopyPropertiesAtIndex(myImage!, 0, nil)! as NSDictionary;
let tiffModel_ = imageDict.value(forKey: "{TIFF}")
let cameraMake = (tiffModel_ as AnyObject).value(forKey: kCGImagePropertyTIFFMake as String)
let cameraModel = (tiffModel_ as AnyObject).value(forKey: kCGImagePropertyTIFFModel as String)
let exifDict_ = imageDict.value(forKey: "{Exif}") as! NSDictionary
let dateTimeOriginal = exifDict_.value(forKey:kCGImagePropertyExifDateTimeOriginal as String) as! NSString
let exposure = exifDict_.value(forKey:kCGImagePropertyExifExposureTime as String)
print ("\(String(describing: cameraMake)) \(String(describing: cameraModel)) \(dateTimeOriginal) \(exposure!)")
答案 2 :(得分:0)
此代码将帮助您获取照片和exif的日期
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true, completion: nil)
if let image = info[.originalImage] as? UIImage {
let assetURL = info[UIImagePickerController.InfoKey.referenceURL] as! NSURL
let asset = PHAsset.fetchAssets(withALAssetURLs: [assetURL as URL], options: nil)
guard let result = asset.firstObject else {
return
}
let imageManager = PHImageManager.default()
imageManager.requestImageData(for: result , options: nil, resultHandler:{
(data, responseString, imageOriet, info) -> Void in
let imageData: NSData = data! as NSData
if let imageSource = CGImageSourceCreateWithData(imageData, nil) {
let imageDict = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)! as NSDictionary
let exifDict_ = imageDict.value(forKey: "{Exif}") as! NSDictionary
let dateTimeOriginal = exifDict_.value(forKey:kCGImagePropertyExifDateTimeOriginal as String) as! NSString
print (" exifDict : \(exifDict_)")
print (" fecha : original \(dateTimeOriginal)")
}
})
picker.dismiss(animated: true, completion: nil)
}
答案 3 :(得分:0)
这是一个示例代码,可以帮助我们读取整个 imageMetadata 并将其转换为字典格式。
guard let imageSource = CGImageSourceCreateWithURL(fileURL as CFURL, nil),
let metadata = CGImageSourceCopyMetadataAtIndex(imageSource, 0, nil),
let tags = CGImageMetadataCopyTags(metadata),
let imageInfo = self.readMetadataTagArr(tagArr: tags) else { return }
然后有一些辅助函数实际上完成了将数据提取/转换为字典格式的所有工作。
/// Reads the Arrays of tags and convert them into a dictionary of [String: Any]
private static func readMetadataTagArr(tagArr: CFArray) -> [String: Any]? {
var result = [String: Any]()
for (_, tag) in (tagArr as NSArray).enumerated() {
let tagMetadata = tag as! CGImageMetadataTag
if let cfName = CGImageMetadataTagCopyName(tagMetadata) {
let name = String(cfName)
result[name] = self.readMetadataTag(metadataTag: tagMetadata)
}
}
return result
}
/// convert CGImageMetadataTag to a dictionary of [String: Any]
private static func readMetadataTag(metadataTag: CGImageMetadataTag) -> [String: Any] {
var result = [String: Any]()
guard let cfName = CGImageMetadataTagCopyName(metadataTag) else { return result }
let name = String(cfName)
let value = CGImageMetadataTagCopyValue(metadataTag)
/// checking the type of `value` object and then performing respective operation on `value`
if CFGetTypeID(value) == CFStringGetTypeID() {
let valueStr = String(value as! CFString)
result[name] = valueStr
} else if CFGetTypeID(value) == CFDictionaryGetTypeID() {
let nsDict: NSDictionary = value as! CFDictionary
result[name] = self.getDictionary(from: nsDict)
} else if CFGetTypeID(value) == CFArrayGetTypeID() {
let valueArr: NSArray = value as! CFArray
for (_, item) in valueArr.enumerated() {
let tagMetadata = item as! CGImageMetadataTag
result[name] = self.readMetadataTag(metadataTag: tagMetadata)
}
} else {
// when the data was of some other type
let descriptionString: CFString = CFCopyDescription(value);
let str = String(descriptionString)
result[name] = str
}
return result
}
/// Converting CGImage Metadata dictionary to [String: Any]
private static func getDictionary(from nsDict: NSDictionary) -> [String: Any] {
var subDictionary = [String: Any]()
for (key, val) in nsDict {
guard let key = key as? String else { continue }
let tempDict: [String: Any] = [key: val]
if JSONSerialization.isValidJSONObject(tempDict) {
subDictionary[key] = val
} else {
let mData = val as! CGImageMetadataTag
let tempDict: [String: Any] = [key: self.readMetadataTag(metadataTag: mData)]
if JSONSerialization.isValidJSONObject(tempDict) {
subDictionary[key] = tempDict
}
}
}
return subDictionary
}
这是提取的所有字典键的列表 https://react-query.tanstack.com/guides/testing