IOS_将GPS等EXIF信息写进任意JPEG图片(不依托UIImagePickerController)

特别鸣谢本群【刀刀 _IOS_南京】 ,兄台发我一份word文档,相当之认真。。。。感动+感谢Ing


Dark老大让我出个帖子,但我接触iOS开发才不过几个月,经历过两个项目,实在没太有多少干货,只知道一些常规知识。翻箱倒柜,终于找到这样一个知识点,就是把gps、时间等exif信息写进jpg图片,以达到不用依靠另外的配置文件、数据库等方法就可保存一张图片的更多附加信息,十分方便。

之前查找iOS中关于保存图片exif信息的资料时,发现网上介绍的方法几乎全是要依托UIImagePickerController来保存,局限性比较大,但我需要将exif信息保存进任意图片,然后图片还可以随意存储在沙盒,不存在相册。最后找到老外的一片文章,英语烂到家的我硬着头皮,终于整理出了我想要的代码:

 

/* 设置图片的gps信息
 * lat、longi:经纬度
 * data:     图片数据
 * imgFilepath:信息写进图片,将图片保存到的路径
 */
+(BOOL)setGPSToImageByLat:(double)latlon:(double)longi imgData:(NSData *)data newImgFilePath:(NSString*)imgFilepath
{
    if(!data || [data length] == 0 ||!imgFilepath || [imgFilepath length] <= 0)
    {
        return NO;
    }
   
    CGImageSourceRef source =CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
    NSDictionary *dict = (__bridgeNSDictionary*)CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
   
    NSMutableDictionary *metaDataDic = [dictmutableCopy];
   
    //GPS
    NSMutableDictionary *gpsDic =[NSMutableDictionary dictionary];
    //[gpsDic setObject:@"N"forKey:(NSString*)kCGImagePropertyGPSLatitudeRef];
    [gpsDic setObject:[NSNumbernumberWithDouble:lat] forKey:(NSString*)kCGImagePropertyGPSLatitude];
    //[gpsDic setObject:@"E"forKey:(NSString*)kCGImagePropertyGPSLongitudeRef];
    [gpsDic setObject:[NSNumbernumberWithDouble:longi] forKey:(NSString *)kCGImagePropertyGPSLongitude];
   
    [metaDataDic setObject:gpsDicforKey:(NSString*)kCGImagePropertyGPSDictionary];
   
    //其他exif信息
    NSMutableDictionary *exifDic =[[metaDataDic objectForKey:(NSString*)kCGImagePropertyExifDictionary]mutableCopy];
    if(!exifDic)
    {
        exifDic = [NSMutableDictionarydictionary];
    }
    NSDateFormatter *dateFormatter =[[NSDateFormatter alloc]init];
    [dateFormattersetFormatterBehavior:NSDateFormatterBehavior10_4];
    [dateFormattersetDateFormat:@"yyyy/MM/dd HH:mm:ss"];
    NSString *EXIFFormattedCreatedDate =[dateFormatter stringFromDate:[NSDate date]];
    [exifDic setObject:EXIFFormattedCreatedDateforKey:(NSString*)kCGImagePropertyExifDateTimeDigitized];
   
    [metaDataDic setObject:exifDicforKey:(NSString*)kCGImagePropertyExifDictionary];
   
    //写进图片
    CFStringRef UTI = CGImageSourceGetType(source);
    NSMutableData *data1 = [NSMutableDatadata];
    CGImageDestinationRef destination =CGImageDestinationCreateWithData((__bridge CFMutableDataRef)data1, UTI, 1,NULL);
    if(!destination)
    {
        return NO;
    }
   
   CGImageDestinationAddImageFromSource(destination, source, 0, (__bridgeCFDictionaryRef)metaDataDic);
   if(!CGImageDestinationFinalize(destination))
    {
        return NO;
    }
   
    //获取documents目录
    NSString *directoryDocuments = [NSHomeDirectory()stringByAppendingPathComponent:@"Documents"];
    //文件的目标路径
    NSString *destDirect = [directoryDocumentsstringByAppendingFormat:@"/%@",kCustomPhotosAlbumDirectory];
    NSFileManager *mgr = [NSFileManagerdefaultManager];
    BOOL isDir = YES;
   if(![mgr fileExistsAtPath:destDirect isDirectory:&isDir])
    {
        //原图路径不存在,创建该路径
        if(![mgrcreateDirectoryAtPath:destDirect withIntermediateDirectories:YES attributes:nilerror:nil])
        {
            return NO;
        }
    }
   
   NSString *path = [NSStringstringWithFormat:@"%@/%@",destDirect,imgFilepath];
    [data1 writeToFile:path atomically:YES];
    NSLog(@"保存成功!path = %@",path);
   
    CFRelease(destination);
    CFRelease(source);
   
    return YES;
}
 
 
//获取图片的exif、gps等信息(path:图片路径)
+(Photo*)getGPSByImageFilePath:(NSString*)path
{
    if(!path || [path length] == 0)
    {
        return nil;
    }
 
    NSURL *url = [NSURL fileURLWithPath:path];
    CGImageSourceRef source =CGImageSourceCreateWithURL((__bridge CFURLRef)url, NULL);
    if(!source)
    {
        return nil;
    }
   
    NSDictionary *dd = [NSDictionarydictionaryWithObjectsAndKeys:[NSNumbernumberWithBool:NO],(NSString*)kCGImageSourceShouldCache, nil];
    CFDictionaryRef dict =CGImageSourceCopyPropertiesAtIndex(source, 0, (__bridge CFDictionaryRef)dd);
    if(!dict)
    {
        return nil;
    }
   
    CFDictionaryRef exif =CFDictionaryGetValue(dict, kCGImagePropertyExifDictionary);
    if(exif)
    {
    }
   
    //获得GPS 的 dictionary
    CFDictionaryRef gps =CFDictionaryGetValue(dict, kCGImagePropertyGPSDictionary);
    if(!gps)
    {
        return nil;
    }
   
    //获取经纬度
    NSString *lat = (__bridgeNSString*)CFDictionaryGetValue(gps, kCGImagePropertyGPSLatitude);
    NSString *lon = (__bridgeNSString*)CFDictionaryGetValue(gps, kCGImagePropertyGPSLongitude);
 
    if(exif)
    {
                          //日期
        NSString *date = (__bridge NSString*)(CFDictionaryGetValue(exif, kCGImagePropertyExifDateTimeDigitized));
    }
   
    CFRelease(dict);
    CFRelease(exif);
    CFRelease(gps);
   
    return photo;
}

 小编:

@刀刀是我看到最认真写技术贴的兄,十分感谢!

话说在图片上标记GPS\时间\等附加信息,是相当有用的技术。而且这个还是不依赖于UIImagePickerController. 仔细琢磨下getGPSByImageFilePath方法,并且有必要回头看看CFDictionaryRef  API的内容了

非常有心意,期待更多力作噢




你可能感兴趣的:(ios,gps,uiimage,CFDictionaryRef)