首页 > 代码库 > iOS图片元数据的读写

iOS图片元数据的读写

图片的本身就是各种图像数据的载体,包含着像素、色彩、灰度等各种数据信息,除此之外,还包含着曝光数据、日期、位置、版权等元数据(metadata)。

何为图片元数据

元数据包括许多重要的信息,常用的有Exif(可交换图像文件格式,Exchangeable image file format)、GPS(位置信息)和TIFF(Tagged Image File Format,标签图像文件格式)。

所谓元数据是指Data about Data,就是用来描述数据的数据。

以Exif为例,其中包含了大量信息:

Image Description 图像描述、来源. 指生成图像的工具Artist 作者 有些相机可以输入使用者的名字Make 生产者 指产品生产厂家Model 型号 指设备型号Orientation方向 有的相机支持,有的不支持XResolution/YResolution X/Y方向分辨率 本栏目已有专门条目解释此问题。ResolutionUnit分辨率单位 一般为PPISoftware软件 显示固件Firmware版本DateTime日期和时间YCbCrPositioning 色相定位ExifOffsetExif信息位置,定义Exif在信息在文件中的写入,有些软件不显示。ExposureTime 曝光时间 即快门速度FNumber光圈系数ExposureProgram曝光程序 指程序式自动曝光的设置,各相机不同,可能是Sutter Priority(快门优先)、Aperture Priority(快门优先)等等。ISO speed ratings感光度ExifVersionExif版本DateTimeOriginal创建时间DateTimeDigitized数字化时间ComponentsConfiguration图像构造(多指色彩组合方案)CompressedBitsPerPixel(BPP)压缩时每像素色彩位 指压缩程度ExposureBiasValue曝光补偿。MaxApertureValue最大光圈MeteringMode测光方式, 平均式测光、中央重点测光、点测光等。Lightsource光源 指白平衡设置Flash是否使用闪光灯。FocalLength焦距,一般显示镜头物理焦距,有些软件可以定义一个系数,从而显示相当于35mm相机的焦距 MakerNote(User Comment)作者标记、说明、记录FlashPixVersionFlashPix版本 (个别机型支持)ColorSpace色域、色彩空间ExifImageWidth(Pixel X Dimension)图像宽度 指横向像素数ExifImageLength(Pixel Y Dimension)图像高度 指纵向像素数Interoperability IFD通用性扩展项定义指针 和TIFF文件相关,具体含义不详FileSource源文件 Compression压缩比。

这些数据就是构成一张图片的元素,也相当于一张图片的名片,包含着丰富的信息。

你可以在此了解更多关于Exif的具体研究。

在开发中使用

目前市场上的大部分智能手机拍摄的照片都支持写入元数据,因此我们可以利用图片的元数据来携带需要添加的数据。在处理图片时,我们往往需要对图片数据进行操作,除了操作其中的图像信息外,我们还可以对图片信息的元数据进行操作,包括存和取。这对于传递数据将是十分便利的,其中一方只需将数据写入图片,另一方通过读取图片的元数据就可获取所要传递的数据,而不需要传除图片之外的任何对象,在实际开发中应用场景很多。

My Codes

  • Metadata read

  • 首先,我们需要借助与UIImagePickerControllerDelegate的代理方法,创建一个UIImagePickerController,在其代理方法- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info中就可获取info,从而获取image对象:

UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
  1. 为获取infometadata,要使用ALAssetsLibraryassetForURL: resultBlock:方法:

 //1. 首先得到Reference URL    NSURL *assetURL = [info objectForKey:UIImagePickerControllerReferenceURL];    //2. 创建一个ALAssetsLibrary    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];    //3. 使用回调方法,得到字典类型的metadata    [library assetForURL:assetURL             resultBlock:^(ALAsset *asset) {                 NSDictionary *imageMetadata = [[NSMutableDictionary alloc] initWithDictionary:asset.defaultRepresentation.metadata];                 NSLog(@"metadata:--%@",imageMetadata);                 NSDictionary *gpsDic = [imageMetadata objectForKey:@"{GPS}"];                 NSDictionary *exifDic = [imageMetadata objectForKey:@"{Exif}"];                 NSDictionary *tiffDic = [imageMetadata objectForKey:@"{TIFF}"];                 //可交换图像文件                 NSLog(@"Exif info:--%@",exifDic);                 //地理位置信息                 NSLog(@"GPS info:--%@",gpsDic);                 //图像文件格式                 NSLog(@"tiff info:--%@",tiffDic);             }
  • Metadata Write

以向图片元数据中写入Exif的kCGImagePropertyExifDateTimeOriginal为例。

1.先按照特定的格式创建一个日期对象:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];[formatter setDateFormat:@"YYYY:MM:dd hh:mm:ss"];NSString *now = [formatter stringFromDate:[NSDate date]];

2.将之前的exifDic中的对应字段值设为当前日期对象now

[exifDic setValue:now forKey:(NSString*)kCGImagePropertyExifDateTimeOriginal];[imageMetadata setValue:exifDic forKey:@"{Exif}"];

3.利用ALAssetsLibrary的writeImageToSavedPhotosAlbum: metadata: completionBlock方法写入并保存:

[library writeImageToSavedPhotosAlbum:[image CGImage] metadata:imageMetadata completionBlock:^(NSURL *assetURL, NSError *error) {                     if (error == nil)                         NSLog(@"metadata write success!");                     else                         NSLog(@"write error:%@",error.userInfo);                 }];

这样,图片的创建时间就被写入并保存了,如果是对相册中已经存在的图片进行此写入操作,则其将被更改创建时间而另存。

  • 扩展

如果你想写入中文或者自定义数据,可以考虑将数据写入到kCGImagePropertyExifUserComment中。

UserComment标签说明
标签号:0x9286;格式:undefined;描述:存储用户的注释,这个标签允许使用两字节的德字符或者 unicode,前8 个字节描述的是字符集,‘JIS‘ 是日文 (著名的有 Kanji)。
‘0x41,0x53,0x43,0x49,0x49,0x00,0x00,0x00‘:ASCII
‘0x4a,0x49,0x53,0x00,0x00,0x00,0x00,0x00‘:JIS
‘0x55,0x4e,0x49,0x43,0x4f,0x44,0x45,0x00‘:Unicode
‘0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00‘:Undefined

UserComment写入的代码实现

NSString *userComment = @"你好,this is a test text for writing data in UserComment";                 [exifDic setValue:userComment forKey:(NSString*)kCGImagePropertyExifUserComment];                 [imageMetadata setValue:exifDic forKey:@"{Exif}"];

为了方便理解和扩展,笔者在Github上提交了一个Deme:ImageMetadata。

iOS图片元数据的读写