我曾经UIImagePickerController在我的iOS应用程序中选择图像,并且知道exif信息可以通过获取info[UIImagePickerControllerMediaMetadata]。但是,当我通过上载图像到服务器时UIImage,大多数exif信息已经被删除。我想知道是否可以在Http请求中将exif信息添加到我的图像中(此后以jpg格式上传的图像)。如果没有,我应该如何解决这个问题?我想更改“制作”,“模型”属性(换句话说,使用什么设备拍摄这张照片)
UIImagePickerController
info[UIImagePickerControllerMediaMetadata]
UIImage
以下是我的代码段:
func Tapped() { let myPickerController = UIImagePickerController() myPickerController.delegate = self myPickerController.sourceType = UIImagePickerControllerSourceType.Camera myPickerController.allowsEditing = false self.presentViewController(myPickerController, animated: true, completion: nil) } func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { let image = info[UIImagePickerControllerOriginalImage] as? UIImage myImageView.image = image UIImageWriteToSavedPhotosAlbum(image!, self, #selector(ViewController.image(_:didFinishSavingWithError:contextInfo:)), nil) self.dismissViewControllerAnimated(true, completion: nil) } func myImageUploadRequest() { let myUrl = NSURL(string: "http://XXXXXX/Uploadfile") let request = NSMutableURLRequest(URL:myUrl!) request.HTTPMethod = "POST" let param = [ "userId" : "7" ] let boundary = generateBoundaryString() request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") let imageData = UIImageJPEGRepresentation(myImageView.image!, 1) if(imageData == nil) { return; } request.HTTPBody = createBodyWithParameters(param, filePathKey: "file", imageDataKey: imageData!, boundary: boundary) myActivityIndicator.startAnimating() let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in if error != nil { print("error=\(error)") return } // You can print out response object print("******* response = \(response)") // Print out response body let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) print("****** response data = \(responseString!)") do{ let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary }catch{ print(error) } dispatch_async(dispatch_get_main_queue(),{ self.myActivityIndicator.stopAnimating() self.myImageView.image = nil }) } task.resume() } func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData { let body = NSMutableData(); if parameters != nil { for (key, value) in parameters! { body.appendString("--\(boundary)\r\n") body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n") body.appendString("\(value)\r\n") } } let filename = "test.jpg" let mimetype = "image/jpg" body.appendString("--\(boundary)\r\n") body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n") body.appendString("Content-Type: \(mimetype)\r\n\r\n") body.appendData(imageDataKey) body.appendString("\r\n") body.appendString("--\(boundary)--\r\n") return body } func generateBoundaryString() -> String { return "Boundary-\(NSUUID().UUIDString)" } extension NSMutableData { func appendString(string: String) { let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true) appendData(data!) } }
是! 最后,我做了一个技巧来修改EXIF信息。首先,您可以通过UIImageJPEGRepresentation从info [UIImagePickerControllerMediaMetadata]和NSData中获取EXIF信息,而无需从EXImage中获取NSData。然后,您可以使用修改后的EXIF信息创建一个新的NSDictionary。之后,在下面调用我的函数,就可以使用修改后的EXIF获取图像NSData!
func saveImageWithImageData(data: NSData, properties: NSDictionary, completion: (data: NSData, path: NSURL) -> Void) { let imageRef: CGImageSourceRef = CGImageSourceCreateWithData((data as CFDataRef), nil)! let uti: CFString = CGImageSourceGetType(imageRef)! let dataWithEXIF: NSMutableData = NSMutableData(data: data) let destination: CGImageDestinationRef = CGImageDestinationCreateWithData((dataWithEXIF as CFMutableDataRef), uti, 1, nil)! CGImageDestinationAddImageFromSource(destination, imageRef, 0, (properties as CFDictionaryRef)) CGImageDestinationFinalize(destination) var paths: [AnyObject] = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) let savePath: String = paths[0].stringByAppendingPathComponent("exif.jpg") let manager: NSFileManager = NSFileManager.defaultManager() manager.createFileAtPath(savePath, contents: dataWithEXIF, attributes: nil) completion(data: dataWithEXIF,path: NSURL(string: savePath)!) print("image with EXIF info converting to NSData: Done! Ready to upload! ") }