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的內容了

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




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章