将EXIF数据保存为JPEG-Swift [英] Saving EXIF data to JPEG - Swift

查看:74
本文介绍了将EXIF数据保存为JPEG-Swift的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试使用UIImagePickerController在应用程序中拍摄照片,将其保存到本地数据库中,然后再上传到服务中.

I am currently trying to shoot photos within an app with the UIImagePickerController, saving it to the local database and upload them later to a service.

但是,似乎元数据(尤其是EXIF)并未自动与此图片捆绑在一起.我试图像这样提取它:

But it seems that the metadata (especially EXIF) are not bundled with this image automatically. I've tried to extract it like this:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{ 
    self.imageDelegate?.saveImage( image: info[UIImagePickerControllerOriginalImage] as! UIImage, metadata: (info[UIImagePickerControllerMediaMetadata] as? NSDictionary)! ) 
    // ...
}

现在我应该具有图像和元数据,但是如何将其存储到JPEG文件中?我需要服务器上图像中的GPS数据.

Now I should have the image and the metadata, but how can I store it into a JPEG file? I need the GPS data in the image on the server.

我目前正在直接从相机胶卷中的UImage创建图像:

I am currently creating the image directly from the UImage from the camera roll:

UIImageJPEGRepresentation(image,CGFloat(Constants.JPEG_QUALITY))

这将被存储并上传.

我已冒用"CGImageDestination"的可能性,但我不知道如何在我的情况下使用它们.

I've red that there might a possibility by using "CGImageDestination" but I have no idea how to use them in my case.

推荐答案

我的解决方案:

func toJpegWithExif(image: UIImage, metadata: NSDictionary, location: CLLocation?) -> Data? {
    return autoreleasepool(invoking: { () -> Data in
        let data = NSMutableData()
        let options = metadata.mutableCopy() as! NSMutableDictionary
        options[ kCGImageDestinationLossyCompressionQuality ] = CGFloat(Constants.JPEG_QUALITY)

        // if location is available, add GPS data, thanks to https://gist.github.com/nitrag/343fe13f01bb0ef3692f2ae2dfe33e86
        if ( nil != location ) {
            let gpsData = NSMutableDictionary()

            let altitudeRef = Int(location!.altitude < 0.0 ? 1 : 0)
            let latitudeRef = location!.coordinate.latitude < 0.0 ? "S" : "N"
            let longitudeRef = location!.coordinate.longitude < 0.0 ? "W" : "E"

            // GPS metadata
            gpsData[(kCGImagePropertyGPSLatitude as String)] = abs(location!.coordinate.latitude)
            gpsData[(kCGImagePropertyGPSLongitude as String)] = abs(location!.coordinate.longitude)
            gpsData[(kCGImagePropertyGPSLatitudeRef as String)] = latitudeRef
            gpsData[(kCGImagePropertyGPSLongitudeRef as String)] = longitudeRef
            gpsData[(kCGImagePropertyGPSAltitude as String)] = Int(abs(location!.altitude))
            gpsData[(kCGImagePropertyGPSAltitudeRef as String)] = altitudeRef
            gpsData[(kCGImagePropertyGPSTimeStamp as String)] = location!.timestamp.isoTime()
            gpsData[(kCGImagePropertyGPSDateStamp as String)] = location!.timestamp.isoDate()
            gpsData[(kCGImagePropertyGPSVersion as String)] = "2.2.0.0"

            options[ kCGImagePropertyGPSDictionary as String ] = gpsData
        }

        let imageDestinationRef = CGImageDestinationCreateWithData(data as CFMutableData, kUTTypeJPEG, 1, nil)!
        CGImageDestinationAddImage(imageDestinationRef, image.cgImage!, options)
        CGImageDestinationFinalize(imageDestinationRef)
        return data as Data
    })
}

extension Date {

    func isoDate() -> String {
        let f = DateFormatter()
        f.timeZone = TimeZone(abbreviation: "UTC")
        f.dateFormat = "yyyy:MM:dd"
        return f.string(from: self)
    }

    func isoTime() -> String {
        let f = DateFormatter()
        f.timeZone = TimeZone(abbreviation: "UTC")
        f.dateFormat = "HH:mm:ss.SSSSSS"
        return f.string(from: self)
    }
}

该方法将UIImage转换为具有来自相机的EXIF数据以及来自CLLocationManager的可选GPS位置的Jpeg.

The method converts the UIImage to a Jpeg with EXIF data from the camera plus an optional GPS location coming from CLLocationManager.

这篇关于将EXIF数据保存为JPEG-Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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