添加GPS元数据字典到AVFoundation拍摄的图像 [英] add GPS metadata dictionary to image taken with AVFoundation in swift

查看:124
本文介绍了添加GPS元数据字典到AVFoundation拍摄的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在swift中用 AVFoundation 拍摄的图像添加GPS元数据。我有下面的代码粘贴,但它不工作。我的错误在哪里?

  let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
let imgDataProvider = CGDataProviderCreateWithCFData(imageData);
let imageRef = CGImageCreateWithJPEGDataProvider(imgDataProvider,nil,true,.RenderingIntentDefault)
let properties = self.getImageProperties(imageData)
let mutableDictionary:NSMutableDictionary = NSMutableDictionary(dictionary:properties)

let newImageData = CFDataCreateMutable(nil,0)
let type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,image / jpgas CFString,kUTTypeImage)
let destination = CGImageDestinationCreateWithData(newImageData,(type?.takeRetainedValue())!, 1,nil)
CGImageDestinationAddImage(destination!,imageRef !, mutableDictionary)
CGImageDestinationFinalize(destination!)
let newImage = newImageData

getImageProperties方法:

  private func getImageProperties(data:NSData) - > NSDictionary {
let imageSourceRef = CGImageSourceCreateWithData(data,nil);
let properties = CGImageSourceCopyPropertiesAtIndex(imageSourceRef !, 0,nil)
let props = properties
return props!
}

getGPSDictionary方法:

  private func getGPSDictionary() - > NSDictionary {
let dictionary = [kCGImagePropertyGPSLatitude as String:54,kCGImagePropertyGPSLongitude as String:23]
return dictionary
}

是的,我知道坐标硬编码到目前为止,但现在重要的是让它工作,我会更新位置。

解决方案

这就是我做到的。这工作在Swift 2.2 iOS 9.2上。
$ b $ pre $ func shutter(sender:AnyObject){
let connection = imageOutput。 connectionWithMediaType(AVMediaTypeVideo)

//设置方向
如果connection.supportsVideoOrientation {
connection.videoOrientation = currentVideoOrientation()
}

imageOutput.captureStillImageAsynchronouslyFromConnection(connection){
(sampleBuffer:CMSampleBuffer!,error:NSError!) - >如果sampleBuffer!= nil {
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)

//获得旧的EXIF
let oldEXIF = self.getEXIFFromImage( imageData)

//将gps信息添加到旧的exif
let newEXIF = self.addGPSToEXIF(oldEXIF,new:self.getGPSDictionaryForLocation(Genba.sharedInstance.gps.currentLocation))

//将图像调整为所需的
let resized = self.resizeNSDataImage(imageData,newSize:Genba.sharedInstance.imageSize)

//将新的exif附加到调整大小image
let attach = self.attachEXIFtoImage(resized,EXIF:newEXIF)

//将文件保存到相机胶卷和应用程序中
self.saveFile(附加)

} else {
debugPrint(self.n,#line,Error capture photo \(error.localizedDescri )
}
}
}

帮手函数在这里

  //结合exif字典
func addGPSToEXIF(old:NSDictionary,new:NSDictionary) - > NSDictionary {

old.setValue(new,forKey:kCGImagePropertyGPSDictionary as String)

返回旧
}

//获取NSDictionary从图像
func getEXIFFromImage(image:NSData) - > NSDictionary {

let imageSourceRef = CGImageSourceCreateWithData(image,nil);

let currentProperties = CGImageSourceCopyPropertiesAtIndex(imageSourceRef !, 0,nil)

let mutableDict = NSMutableDictionary(dictionary:currentProperties!)

return mutableDict



//将EXIF DIctionary数据附加到图像
func attachEXIFtoImage(image:NSData,EXIF:NSDictionary) - > NSData {

让imageDataProvider:CGDataProviderRef = CGDataProviderCreateWithCFData(image)!

让imageRef:CGImageRef = CGImageCreateWithJPEGDataProvider(imageDataProvider,nil,true,.RenderingIntentDefault)!

let newImageData:CFMutableDataRef = CFDataCreateMutable(nil,0)

let type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,image / jpgas CFString,kUTTypeImage)

let destination:CGImageDestinationRef = CGImageDestinationCreateWithData(newImageData,(type?.takeRetainedValue())!, 1,nil)!

CGImageDestinationAddImage(destination,imageRef,EXIF as CFDictionaryRef)

CGImageDestinationFinalize(目标)

返回newImageData作为NSData

}
//用EXIF $ b $保存应用程序中的文件func saveFile(image:NSData){
//将文件保存为
let dataPath = Genba.sharedInstance.userdata_save_folder
让fileExists = dataPath.checkResourceIsReachableAndReturnError(nil)
if fileExists {

let formatter = NSDateFormatter()
formatter.dateFormat =YM-dd_HH-mm-ss
let time = formatter.stringFromDate(NSDate())

let savefilepath = dataPath.URLByAppendingPathComponent(time +。jpg)

let result = image.writeToURL(savefilepath ,原子:false)

如果结果{
savePhotoToLibraryWithURL(savefilepath)
} else {
debugPrint(n,#行,保存失败)
}


//调整NSData的图像大小
func resizeNSDataImage(inputImage:NSData,newSize:CGSize) - > NSData {

var smallerImage:NSData? = nil

image image = UIImage(data:inputImage)

UIGraphicsBeginImageContext(newSize)

image!.drawInRect(CGRect(origin:CGPointZero, newImage = UIGephicsGetImageFromCurrentImageContext()

UIGraphicsEndImageContext()

smallImage = UIImageJPEGRepresentation
返回小图!
}

func savePhotoToLibraryWithURL(image:NSURL){

  let photoLibrary = PHPhotoLibrary.sharedPhotoLibrary()

photoLibrary.performChanges({
PHAssetChangeRequest.creationRequestForAssetFromImageAtFileURL(image)
}){(成功:Bool,错误:NSError?) - >如果成功{b
$ b} else {
print(self.n,#line,写入照片库时出错:\(error!.localizedDescription)),则无效





code $ pre

I'm trying to add GPS metadata to the image taken with AVFoundation in swift. I have the code pasted below but it doesn't work yet. Where is my mistake?

let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
let imgDataProvider = CGDataProviderCreateWithCFData(imageData);
let imageRef = CGImageCreateWithJPEGDataProvider(imgDataProvider, nil, true, .RenderingIntentDefault)
let properties = self.getImageProperties(imageData)
let mutableDictionary: NSMutableDictionary = NSMutableDictionary(dictionary: properties)
mutableDictionary.setValue(self.getGPSDictionary(), forKey: kCGImagePropertyGPSDictionary as String)
let newImageData = CFDataCreateMutable(nil, 0)
let type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, "image/jpg" as CFString, kUTTypeImage)
let destination = CGImageDestinationCreateWithData(newImageData, (type?.takeRetainedValue())!, 1, nil)
CGImageDestinationAddImage(destination!, imageRef!, mutableDictionary)
CGImageDestinationFinalize(destination!)
let newImage = newImageData

getImageProperties method:

private func getImageProperties(data: NSData) -> NSDictionary {
    let imageSourceRef = CGImageSourceCreateWithData(data, nil);
    let properties = CGImageSourceCopyPropertiesAtIndex(imageSourceRef!, 0, nil)
    let props = properties
    return props!
}

getGPSDictionary method:

private func getGPSDictionary() -> NSDictionary {
    let dictionary = [kCGImagePropertyGPSLatitude as String :"54",kCGImagePropertyGPSLongitude as String :"23"]
    return dictionary
}

Yes, i know that coordinates are hardcoded so far but important for now is to make it working, i will update location.

解决方案

This is how I did it. This worked on Swift 2.2 iOS 9.2

@IBAction func shutter(sender: AnyObject) {
    let connection = imageOutput.connectionWithMediaType(AVMediaTypeVideo)

    // set the orientation
    if connection.supportsVideoOrientation {
        connection.videoOrientation = currentVideoOrientation()
    }

    imageOutput.captureStillImageAsynchronouslyFromConnection(connection) {
        (sampleBuffer: CMSampleBuffer!, error: NSError!) -> Void in
        if sampleBuffer != nil {
            let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)

            // get the old EXIF
            let oldEXIF = self.getEXIFFromImage(imageData)

            // add gps info to the old exif
            let newEXIF = self.addGPSToEXIF(oldEXIF, new: self.getGPSDictionaryForLocation(Genba.sharedInstance.gps.currentLocation))

            // resize the image to desired
            let resized = self.resizeNSDataImage(imageData, newSize: Genba.sharedInstance.imageSize)

            // attach the new exif to the resized image
            let attached = self.attachEXIFtoImage(resized, EXIF: newEXIF)

            // save the file to the camera roll and inside the app
            self.saveFile(attached)

        } else {
            debugPrint(self.n,#line,"Error capturing photo \(error.localizedDescription)")
        }
    }
}

The helper functions are here

// combine exif dictionaries
func addGPSToEXIF(old:NSDictionary, new:NSDictionary) -> NSDictionary {

    old.setValue(new, forKey: kCGImagePropertyGPSDictionary as String)

    return old
}

// get an NSDictionary from an image
func getEXIFFromImage(image:NSData) -> NSDictionary {

    let imageSourceRef = CGImageSourceCreateWithData(image, nil);

    let currentProperties = CGImageSourceCopyPropertiesAtIndex(imageSourceRef!, 0, nil)

    let mutableDict = NSMutableDictionary(dictionary: currentProperties!)

    return mutableDict

}

// Attach EXIF DIctionary data to an image
func attachEXIFtoImage(image:NSData, EXIF:NSDictionary) -> NSData {

    let imageDataProvider:CGDataProviderRef = CGDataProviderCreateWithCFData(image)!

    let imageRef:CGImageRef = CGImageCreateWithJPEGDataProvider(imageDataProvider, nil, true, .RenderingIntentDefault)!

    let newImageData:CFMutableDataRef = CFDataCreateMutable(nil, 0)

    let type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, "image/jpg" as CFString, kUTTypeImage)

    let destination:CGImageDestinationRef = CGImageDestinationCreateWithData(newImageData, (type?.takeRetainedValue())!, 1, nil)!

    CGImageDestinationAddImage(destination, imageRef, EXIF as CFDictionaryRef)

    CGImageDestinationFinalize(destination)

    return newImageData as NSData

}
// save file within app with EXIF
func saveFile(image: NSData) {
       // Saves the file out
    let dataPath = Genba.sharedInstance.userdata_save_folder
    let fileExists = dataPath.checkResourceIsReachableAndReturnError(nil)
    if fileExists {

        let formatter = NSDateFormatter()
        formatter.dateFormat = "Y-M-dd_HH-mm-ss"
        let time = formatter.stringFromDate(NSDate())

        let savefilepath = dataPath.URLByAppendingPathComponent(time+".jpg")

        let result =  image.writeToURL(savefilepath, atomically: false)

        if result {
            savePhotoToLibraryWithURL(savefilepath)
        } else {
            debugPrint(n,#line,"failed to save")
        }
    }
}
// resize image from NSData
func resizeNSDataImage (inputImage:NSData, newSize:CGSize) -> NSData {

    var smallerImage:NSData? = nil

    let image = UIImage(data: inputImage)

    UIGraphicsBeginImageContext(newSize)

    image!.drawInRect(CGRect(origin: CGPointZero, size: newSize))

    let newImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    smallerImage = UIImageJPEGRepresentation(newImage, 1)

    return smallerImage!
} 

func savePhotoToLibraryWithURL(image: NSURL) {

    let photoLibrary = PHPhotoLibrary.sharedPhotoLibrary()

    photoLibrary.performChanges({
        PHAssetChangeRequest.creationRequestForAssetFromImageAtFileURL(image)
    }) { (success: Bool, error: NSError?) -> Void in
        if success {

        } else {
            print(self.n,#line,"Error writing to photo library: \(error!.localizedDescription)")

        }
    }
}

这篇关于添加GPS元数据字典到AVFoundation拍摄的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆