我知道如何使用 ALAssets 保存元数据.但是,我想保存图像,或将其上传到某个地方,exif 完好无损.我有 exif 数据作为 NSDictionary.但是我怎样才能将它正确地注入 UIImage(或者可能是 NSData JPEG 表示)?
I am aware of how to save metadata using ALAssets. But, I want to save an image, or upload it somewhere, with exif intact. I have exif data as an NSDictionary. But how can I inject it properly into a UIImage (or probably an NSData JPEG representation)?
UIImage 不包含元数据信息(被剥离).因此,如果您想在不使用 imagepicker 方法的情况下保存它(不在相机胶卷中):
UIImage does not contain metadata information (it is stripped). So if you want to save it without using the imagepicker method (not in camera roll):
按照此处的答案写入元数据完整的文件:
Follow the answer here to write to a file with the metadata intact:
图片的exif数据设置问题
不知道为什么会被否决,但方法如下:
no idea why would this be downvoted but here is the method:
在这种情况下,我通过 AVFoundation 获取图像,这就是
In this case im getting the image through AVFoundation and this is what goes in the
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection
completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
// code here
}
块代码:
CFDictionaryRef metaDict = CMCopyDictionaryOfAttachments(NULL, imageSampleBuffer, kCMAttachmentMode_ShouldPropagate);
CFMutableDictionaryRef mutable = CFDictionaryCreateMutableCopy(NULL, 0, metaDict);
// Create formatted date
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:timeZone];
[formatter setDateFormat:@"HH:mm:ss.SS"];
// Create GPS Dictionary
NSDictionary *gpsDict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:fabs(loc.coordinate.latitude)], kCGImagePropertyGPSLatitude
, ((loc.coordinate.latitude >= 0) ? @"N" : @"S"), kCGImagePropertyGPSLatitudeRef
, [NSNumber numberWithFloat:fabs(loc.coordinate.longitude)], kCGImagePropertyGPSLongitude
, ((loc.coordinate.longitude >= 0) ? @"E" : @"W"), kCGImagePropertyGPSLongitudeRef
, [formatter stringFromDate:[loc timestamp]], kCGImagePropertyGPSTimeStamp
, [NSNumber numberWithFloat:fabs(loc.altitude)], kCGImagePropertyGPSAltitude
, nil];
// The gps info goes into the gps metadata part
CFDictionarySetValue(mutable, kCGImagePropertyGPSDictionary, (__bridge void *)gpsDict);
// Here just as an example im adding the attitude matrix in the exif comment metadata
CMRotationMatrix m = att.rotationMatrix;
GLKMatrix4 attMat = GLKMatrix4Make(m.m11, m.m12, m.m13, 0, m.m21, m.m22, m.m23, 0, m.m31, m.m32, m.m33, 0, 0, 0, 0, 1);
NSMutableDictionary *EXIFDictionary = (__bridge NSMutableDictionary*)CFDictionaryGetValue(mutable, kCGImagePropertyExifDictionary);
[EXIFDictionary setValue:NSStringFromGLKMatrix4(attMat) forKey:(NSString *)kCGImagePropertyExifUserComment];
CFDictionarySetValue(mutable, kCGImagePropertyExifDictionary, (__bridge void *)EXIFDictionary);
NSData *jpeg = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer] ;
在此代码之后,您将在 jpeg nsdata 中获得您的图像,并在可变 cfdictionary 中获得该图像的对应字典.
After this code you will have your image in the jpeg nsdata and the correspoding dictionary for that image in the mutable cfdictionary.
你现在要做的就是:
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)jpeg, NULL);
CFStringRef UTI = CGImageSourceGetType(source); //this is the type of image (e.g., public.jpeg)
NSMutableData *dest_data = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)dest_data,UTI,1,NULL);
if(!destination) {
NSLog(@"***Could not create image destination ***");
}
//add the image contained in the image source to the destination, overidding the old metadata with our modified metadata
CGImageDestinationAddImageFromSource(destination,source,0, (CFDictionaryRef) mutable);
//tell the destination to write the image data and metadata into our data object.
//It will return false if something goes wrong
BOOL success = CGImageDestinationFinalize(destination);
if(!success) {
NSLog(@"***Could not create data from image destination ***");
}
//now we have the data ready to go, so do whatever you want with it
//here we just write it to disk at the same path we were passed
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"ImagesFolder"];
NSError *error;
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder
// NSString *imageName = @"ImageName";
NSString *fullPath = [dataPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.jpg", name]]; //add our image to the path
[dest_data writeToFile:fullPath atomically:YES];
//cleanup
CFRelease(destination);
CFRelease(source);
请注意我不是使用 ALAssets 而是直接保存到我选择的文件夹中.
Note how I'm not saving using the ALAssets but directly into a folder of my choice.
顺便说一句,大部分代码都可以在我最初发布的链接中找到.
Btw most of this code can be found in the link I posted at first.
这篇关于如何将 exif 元数据写入图像(不是相机胶卷,只是 UIImage 或 JPEG)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!