iOS Swift + Alamofire 上传带exif数据的照片
iOS Swift + Alamofire upload photos with exif data
我正在使用 Alamofire to upload multiple files at the same time to Open Asset using their REST API 并且我能够让它工作,但是,大部分 EXIF 数据都被删除了。不幸的是,EXIF 数据是必须的,因为我们需要能够通过各种 Web 客户端挖掘出 GPS 标签和其他一些东西。
经过一些研究,我发现问题是因为我正在使用 UIImageJPEGRepresentation
将照片转换为 NSData
(这是 Alamofire
所期望的或文件 URL,它我不认为对我有用?)。
我也在使用 BSImagePicker library to allow the user to take/select multiple photos, which returns a an array of PHAsset,然后将其转换为 NSData
。这是我执行此操作的函数(其中 collectedImages
是全局字典):
func compressPhotos(assets: [PHAsset]) -> Void {
for asset in assets {
let filename = self.getOriginalFilename(asset)
let assetImage = self.getAssetPhoto(asset)
let compressedImage = UIImageJPEGRepresentation(assetImage, 0.5)! // bye bye metadata :(
collectedImages[filename] = compressedImage
print("compressed image: \(filename)")
}
}
如果我可以使用从 PHAsset
到 phone 本地图像的完整路径,我想我可以保留 EXIF 数据,但 Alamofire
似乎不支持那。我希望我错了。这是我的上传者:
func uploadPhotos(projectId: String, categoryId: String, data: [String: NSData], completionHandler: (AnyObject?, NSError?) -> ()) {
var jsonBody = [AnyObject]() //lazy
Alamofire.upload(
.POST,
self.url + "/Files",
multipartFormData: { multipartFormData in
for (filename, img) in data {
jsonBody.append(["project_id": projectId, "category_id": categoryId, "original_filename": filename])
multipartFormData.appendBodyPart(data: img, name: "file", fileName: filename, mimeType: "image/jpeg")
print("img size: \(img.length)")
}
let jsonData = jsonToNSData(jsonBody)
print("_jsonBody: \(jsonBody)")
multipartFormData.appendBodyPart(data: jsonData!, name: "_jsonBody")
print("multipart: \(multipartFormData)")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
switch response.result {
case .Success(let value):
completionHandler(value as? NSArray, nil)
case .Failure(let error):
completionHandler(nil, error)
}
}
case .Failure(let encodingError):
print(encodingError)
}
}
)
}
所以我的问题是,如何在保留所有 EXIF 数据的同时上传多张照片(同时也传递其他参数)? Alamofire
是一个很棒的库,我想在这里使用它,但如果我不能保留 EXIF 数据,我不会在上传过程中使用它。
我认为您可以先从 PHAsset 中获取文件 URL,然后在调用 multipartFormData.appendBodyPart(...) 时使用该文件 URL。像这样:
从 PHAsset 获取 URL:
[asset requestContentEditingInputWithOptions:editOptions
completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSURL *imageURL = contentEditingInput.fullSizeImageURL;
}];
在 AlamoFire API 中使用文件 URL:
multipartFormData.appendBodyPart(fileURL: imageURL, name: "image")
我不确定为什么 fullSizeImageURL
有问题,但它确实引导我走上了正确的道路,因为我能够通过将图像设为 NSData
来实现它] 从这样的文件路径:
asset.requestContentEditingInputWithOptions(PHContentEditingInputRequestOptions()) { (input, _) in
let fileURL = input!.fullSizeImageURL?.filePathURL
let data = NSData(contentsOfFile: fileURL!.path!)!
然后我只是在 Alamofire.request()
中将其作为 data
参数传递。这保留了所有原始照片元数据。
我正在使用 Alamofire to upload multiple files at the same time to Open Asset using their REST API 并且我能够让它工作,但是,大部分 EXIF 数据都被删除了。不幸的是,EXIF 数据是必须的,因为我们需要能够通过各种 Web 客户端挖掘出 GPS 标签和其他一些东西。
经过一些研究,我发现问题是因为我正在使用 UIImageJPEGRepresentation
将照片转换为 NSData
(这是 Alamofire
所期望的或文件 URL,它我不认为对我有用?)。
我也在使用 BSImagePicker library to allow the user to take/select multiple photos, which returns a an array of PHAsset,然后将其转换为 NSData
。这是我执行此操作的函数(其中 collectedImages
是全局字典):
func compressPhotos(assets: [PHAsset]) -> Void {
for asset in assets {
let filename = self.getOriginalFilename(asset)
let assetImage = self.getAssetPhoto(asset)
let compressedImage = UIImageJPEGRepresentation(assetImage, 0.5)! // bye bye metadata :(
collectedImages[filename] = compressedImage
print("compressed image: \(filename)")
}
}
如果我可以使用从 PHAsset
到 phone 本地图像的完整路径,我想我可以保留 EXIF 数据,但 Alamofire
似乎不支持那。我希望我错了。这是我的上传者:
func uploadPhotos(projectId: String, categoryId: String, data: [String: NSData], completionHandler: (AnyObject?, NSError?) -> ()) {
var jsonBody = [AnyObject]() //lazy
Alamofire.upload(
.POST,
self.url + "/Files",
multipartFormData: { multipartFormData in
for (filename, img) in data {
jsonBody.append(["project_id": projectId, "category_id": categoryId, "original_filename": filename])
multipartFormData.appendBodyPart(data: img, name: "file", fileName: filename, mimeType: "image/jpeg")
print("img size: \(img.length)")
}
let jsonData = jsonToNSData(jsonBody)
print("_jsonBody: \(jsonBody)")
multipartFormData.appendBodyPart(data: jsonData!, name: "_jsonBody")
print("multipart: \(multipartFormData)")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
switch response.result {
case .Success(let value):
completionHandler(value as? NSArray, nil)
case .Failure(let error):
completionHandler(nil, error)
}
}
case .Failure(let encodingError):
print(encodingError)
}
}
)
}
所以我的问题是,如何在保留所有 EXIF 数据的同时上传多张照片(同时也传递其他参数)? Alamofire
是一个很棒的库,我想在这里使用它,但如果我不能保留 EXIF 数据,我不会在上传过程中使用它。
我认为您可以先从 PHAsset 中获取文件 URL,然后在调用 multipartFormData.appendBodyPart(...) 时使用该文件 URL。像这样:
从 PHAsset 获取 URL:
[asset requestContentEditingInputWithOptions:editOptions completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) { NSURL *imageURL = contentEditingInput.fullSizeImageURL; }];
在 AlamoFire API 中使用文件 URL:
multipartFormData.appendBodyPart(fileURL: imageURL, name: "image")
我不确定为什么 fullSizeImageURL
有问题,但它确实引导我走上了正确的道路,因为我能够通过将图像设为 NSData
来实现它] 从这样的文件路径:
asset.requestContentEditingInputWithOptions(PHContentEditingInputRequestOptions()) { (input, _) in
let fileURL = input!.fullSizeImageURL?.filePathURL
let data = NSData(contentsOfFile: fileURL!.path!)!
然后我只是在 Alamofire.request()
中将其作为 data
参数传递。这保留了所有原始照片元数据。