将元数据写入映像时遇到问题 [英] Problem in writing metadata to image
问题描述
我使用AvFoundation拍摄静态图片,并将gps信息添加到元数据,并使用素材资源库保存到相册,但gps信息不会保存。
I am using AvFoundation to take still image and adding gps info to metadata and saving to a photo album using Asset library but gps info is not saving at all.
这里是我的代码...
here is my code...
[self.stillImageTaker captureStillImageAsynchronouslyFromConnection:videoConnection
completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error)
{
if (imageDataSampleBuffer != NULL)
{
CFDictionaryRef exifAttachments = CMGetAttachment(imageDataSampleBuffer,kCGImagePropertyExifDictionary, NULL);
CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL, imageDataSampleBuffer, kCMAttachmentMode_ShouldPropagate);
NSDictionary *gpsDict = [NSDictionary dictionaryWithObjectsAndKeys:@"1",kCGImagePropertyGPSVersion,
@"78.4852",kCGImagePropertyGPSLatitude,@"32.1456",kCGImagePropertyGPSLongitude, nil];
CMSetAttachment(imageDataSampleBuffer,kCGImagePropertyGPSDictionary,gpsDict,kCMAttachmentMode_ShouldPropagate);
CFDictionaryRef newMetadata = CMCopyDictionaryOfAttachments(NULL, imageDataSampleBuffer, kCMAttachmentMode_ShouldPropagate);
CFDictionaryRef gpsAttachments = CMGetAttachment(imageDataSampleBuffer,kCGImagePropertyGPSDictionary, NULL);
if (exifAttachments)
{ // Attachments may be read or additional ones written
}
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
/
NSDictionary *newDict = (NSDictionary *)newMetadata;
[library writeImageToSavedPhotosAlbum:[image CGImage]
metadata:newDict completionBlock:^(NSURL *assetURL, NSError *error)
{
if (error)
{
}
}];
[library release];
[image release];
CFRelease(metadataDict);
CFRelease(newMetadata);
}
else if (error)
{
}
}];
推荐答案
我认为这个主题的文档不是很好,所以我通过查看相机应用程序拍摄的照片的元数据并尝试复制它来解决它。
I had exactly the same problem. I think the documentation on this topic isn't great, so I solved it in the end by looking at the metadata of a photo taken by the Camera app and trying to replicate it.
以下是相机应用程序保存的属性的运行:
Here's a run down of the properties the Camera app saves:
- kCGImagePropertyGPSLatitude
strong>(NSNumber) (十进制格式的经度) - kCGImagePropertyGPSLatitudeRef
(NSString) - kCGImagePropertyGPSLongitudeRef
(NSString) (E或W) - kCGImagePropertyGPSTimeStamp
(NSString)(格式为04:30:51.71
(UTC时间戳))
- kCGImagePropertyGPSLatitude (NSNumber) (Latitude in decimal format)
- kCGImagePropertyGPSLongitude (NSNumber) (Longitude in decimal format)
- kCGImagePropertyGPSLatitudeRef (NSString) (Either N or S)
- kCGImagePropertyGPSLongitudeRef (NSString) (Either E or W)
- kCGImagePropertyGPSTimeStamp (NSString) (Of the format 04:30:51.71 (UTC timestamp))
如果你坚持这些,你应该很好。下面是一个示例:
If you stick to these you should be fine. Here's a sample:
CFDictionaryRef metaDict = CMCopyDictionaryOfAttachments(NULL, imageDataSampleBuffer, kCMAttachmentMode_ShouldPropagate);
CFMutableDictionaryRef mutable = CFDictionaryCreateMutableCopy(NULL, 0, metaDict);
NSDictionary *gpsDict = [NSDictionary
dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:self.currentLocation.coordinate.latitude], kCGImagePropertyGPSLatitude,
@"N", kCGImagePropertyGPSLatitudeRef,
[NSNumber numberWithFloat:self.currentLocation.coordinate.longitude], kCGImagePropertyGPSLongitude,
@"E", kCGImagePropertyGPSLongitudeRef,
@"04:30:51.71", kCGImagePropertyGPSTimeStamp,
nil];
CFDictionarySetValue(mutable, kCGImagePropertyGPSDictionary, gpsDict);
// Get the image
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
// Get the assets library
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:[image CGImage] metadata:mutable completionBlock:captureComplete];
这一切都在你的AVCaptureConnection对象的captureStillImageAsynchronouslyFromConnection方法的completionHandler中,self.currentLocation只是CLLocation。我硬编码时间戳和Lat / Lng Refs为例子保持简单。
This is all in the completionHandler of the captureStillImageAsynchronouslyFromConnection method of your AVCaptureConnection object, and self.currentLocation is just a CLLocation. I hardcoded the timestamp and Lat/Lng Refs for the example to keep things simple.
希望这有助于!
这篇关于将元数据写入映像时遇到问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!