在进行照片相关处理时,就会遇到如何保留原始照片的图像信息,一些图片分享社区通常会显示作者所使用的拍摄设备和曝光信息等等,来对所拍摄照片在技术参数的细节分享。

什么是EXIF

可交换图像文件格式常被简称为Exif(Exchangeable image file format),是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据。

更多详细介绍EXIF

原因

利用ImageIO可以打印一下metadata,下面是一张JPEG图片正常情况下的metadata:

{

ColorModel = RGB;

DPIHeight = 72;

DPIWidth = 72;

Depth = 8;

Orientation = 1;

PixelHeight = 1080;

PixelWidth = 1440;

ProfileName = "sRGB IEC61966-2.1";

"{Exif}" = {

ApertureValue = "2.52606882168926";

BrightnessValue = "2.87380073800738";

ColorSpace = 1;

ComponentsConfiguration = (

1,

2,

3,

0

);

DateTimeDigitized = "2016:01:31 23:44:07";

DateTimeOriginal = "2016:01:31 23:44:07";

ExifVersion = (

2,

2,

1

);

ExposureBiasValue = 0;

ExposureMode = 0;

ExposureProgram = 2;

ExposureTime = "0.05";

FNumber = "2.4";

Flash = 24;

FlashPixVersion = (

1,

0

);

FocalLenIn35mmFilm = 33;

FocalLength = "4.12";

ISOSpeedRatings = (

50

);

LensMake = Apple;

LensModel = "iPhone 5 back camera 4.12mm f/2.4";

LensSpecification = (

"4.12",

"4.12",

"2.4",

"2.4"

);

MeteringMode = 5;

PixelXDimension = 1440;

PixelYDimension = 1080;

SceneCaptureType = 0;

SceneType = 1;

SensingMethod = 2;

ShutterSpeedValue = "4.321956769055745";

SubjectArea = (

1631,

1223,

1795,

1077

);

SubsecTimeDigitized = 336;

SubsecTimeOriginal = 336;

WhiteBalance = 0;

};

"{JFIF}" = {

DensityUnit = 0;

JFIFVersion = (

1,

0,

1

);

XDensity = 72;

YDensity = 72;

};

"{TIFF}" = {

DateTime = "2016:01:31 23:44:07";

Make = Apple;

Model = "iPhone 5";

Orientation = 1;

ResolutionUnit = 2;

Software = "9.2";

XResolution = 72;

YResolution = 72;

};

}

可能还会有些GPS信息等.

很多时候我们拿到图片后客户端会需要进行一些处理,例如压缩,缩放等等,避免传输很大的图片浪费资源。这时候对图片的信息就会有损失, 进行数据转换时会用到如下函数:

UIImagePNGRepresentation(UIImage * image);

UIImageJPEGRepresentation(UIImage * image, CGFloat compressionQuality);

以上两个函数将UIImage转NSData 都是将图片质量进行压缩,在实际测试中发现是会将EXIF信息丢失。

UIImagePNGRepresentation

{

ColorModel = RGB;

Depth = 8;

PixelHeight = 3024;

PixelWidth = 4032;

ProfileName = "sRGB IEC61966-2.1";

"{PNG}" = {

Chromaticities = (

"0.3127",

"0.329",

"0.64",

"0.33",

"0.3",

"0.6000000000000001",

"0.15",

"0.06"

);

Gamma = "0.45455";

InterlaceType = 0;

sRGBIntent = 0;

};

}

UIImageJPEGRepresentation

{

ColorModel = RGB;

Depth = 8;

Orientation = 6;

PixelHeight = 3024;

PixelWidth = 4032;

ProfileName = "sRGB IEC61966-2.1";

"{Exif}" = {

ColorSpace = 1;

PixelXDimension = 4032;

PixelYDimension = 3024;

};

"{JFIF}" = {

DensityUnit = 0;

JFIFVersion = (

1,

0,

1

);

XDensity = 72;

YDensity = 72;

};

"{TIFF}" = {

Orientation = 6;

};

}

这就导致在上传图片时本身图片的EXIF信息就已经不对了。

那怎么解决上传图片时保留EXIF信息呢?

1、最简单粗暴的方式就是直接传原图,不进行任何处理,这样就不丢失了。(但这样图片动不动就好几M,很浪费资源)

2、将原图的EXIF信息取出,再设置给处理好的图片,最后传输图片到服务器的过程中不要将NSData转为UIImage即可,也就是说处理好后的图片不要在进行转换以免丢失EXIF信息。

Demo:

ALAsset *asset = ..;

UIImage *tempImg = [UIImage imageWithCGImage:asset.defaultRepresentation.fullScreenImage];

//保存到程序的缓存目录

[SysTool createFileExistsAtPath:kUploadCachePath];

NSString *fileName = [ImageTool createUploadFileName];

NSString *filePath = [NSString stringWithFormat:@"%@/%@",kUploadCachePath,fileName];

if ([ImageTool saveImageCompress:tempImg WithName:fileName path:kUploadCachePath]) {

[_photoList addObject:filePath];

}

ALAssetRepresentation *image_representation = [asset defaultRepresentation];

// 取出原图exif、tiff等信息

CFDictionaryRef imageMetaData = (__bridge CFDictionaryRef)image_representation.metadata;

// 压缩的图片重写exif/tiff信息

NSData *compressData = [NSData dataWithContentsOfFile:filePath];

NSData *exifData = [ImageTool createMetaData:compressData metaDic:(__bridge NSDictionary *)imageMetaData];

// 上传图片到服务器...

[Upload data:exifData];

ImageTool

+ (NSData *)createMetaData:(NSData *)imgData metaDic:(NSDictionary *)metaDic {

// 1原图exif/tiff信息

CFDictionaryRef exif = (CFDictionaryRef)CFDictionaryGetValue((__bridge CFDictionaryRef)metaDic, kCGImagePropertyExifDictionary);

CFDictionaryRef tiff = (CFDictionaryRef)CFDictionaryGetValue((__bridge CFDictionaryRef)metaDic, kCGImagePropertyTIFFDictionary);

// 2获取压缩的图片

CGImageSourceRef compressSource = CGImageSourceCreateWithData((__bridge CFDataRef)imgData, NULL);

CFDictionaryRef compressImageMetaData = CGImageSourceCopyPropertiesAtIndex(compressSource,0,NULL);

CFMutableDictionaryRef compressImageMetaDataMu = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 50, compressImageMetaData);

// 3将原来的exif/tiff等信息设置到压缩后的图片上

if (exif) {

CFDictionarySetValue(compressImageMetaDataMu, kCGImagePropertyExifDictionary, exif);

}

if (tiff) {

CFDictionarySetValue(compressImageMetaDataMu, kCGImagePropertyTIFFDictionary, tiff);

}

NSData *exifData = [self saveImageWithImageData:imgData Properties:(__bridge NSDictionary*)compressImageMetaDataMu];

return exifData;

}

// 将图片的exif信息写入到图片流

+ (NSData *)saveImageWithImageData:(NSData *)data Properties:(NSDictionary *)properties {

NSMutableDictionary *dataDic = [NSMutableDictionary dictionaryWithDictionary:properties];

// 设置properties属性

CGImageSourceRef imageRef = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);

CFStringRef uti = CGImageSourceGetType(imageRef);

NSMutableData *data1 = [NSMutableData data];

CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)data1, uti, 1, NULL);

if (!destination) {

NSLog(@"error");

return nil;

}

CGImageDestinationAddImageFromSource(destination, imageRef, 0, (__bridge CFDictionaryRef)dataDic);

BOOL check = CGImageDestinationFinalize(destination);

if (!check) {

NSLog(@"error");

return nil;

}

CFRelease(destination);

CFRelease(uti);

return data1;

}

其他

当拍照保存到相册以往我们都是简单的调用UIImagePickerController,用系统相机拍照然后直接调用以下API也是会丢失EXIF:

UIImageWriteToSavedPhotosAlbum(UIImage *image, __nullable id completionTarget, __nullable SEL completionSelector, void * __nullable contextInfo);

所以可以调用ALAssetsLibrary的API:

// 保存到系统相册,并附带meta信息

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

[library writeImageToSavedPhotosAlbum:imageToSave.CGImage metadata:(__bridge NSDictionary*)metaDic completionBlock:^(NSURL *assetURL, NSError *error) {

}];

保存到系统相册对比

php 图片压缩 保留exif,保留图片原有的EXIF相关推荐

  1. DPG图片压缩技术和webp图片格式

    DPG图片压缩技术和webp图片格式 一.DPG图片压缩技术 京东自主研发推出的DPG图片压缩技术,经测试该技术,可以直接节省用户近50%的浏览量,极大地提升了用户的网页打开的速度.能够兼容JPEG, ...

  2. java-png图片压缩,解决png图片压缩后背景变黑问题

    java-png图片压缩,解决png图片压缩后背景变黑问题 参考文章: (1)java-png图片压缩,解决png图片压缩后背景变黑问题 (2)https://www.cnblogs.com/yinj ...

  3. 如何快速图片压缩指定大小?图片压缩到200k以内的方法

    图片压缩到200k以内的介绍 在现代社交媒体和网页设计中,高质量的图片是必不可少的.但是,大型图像文件可能会导致页面加载时间过长,从而影响用户体验.这时就需要使用图片压缩技术来将图片文件大小减小到合理 ...

  4. php 图片压缩旋转,移动端图片上传旋转、压缩问题的解决方案

    本篇文章就给大家带来移动端图片上传旋转.压缩问题的解决方案.有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助. 前言 在手机上通过网页 input 标签拍照上传图片,有一些手机会出现图片 ...

  5. vue图片压缩不失真_图片压缩会失真?快试试这几个无损压缩神器。

    前端通常在做网页的时候 会出现图片加载慢的情况 在这里我通常会将图片进行压缩 但是通常情况下 观众会认为 图片压缩会出现失真的现象 在这里我会向大家推荐几款图片压缩的工具 基本上会实现无损压缩 1.T ...

  6. python实现图片压缩_python如何实现图片压缩

    本工具是通过将图片上传到第三方网站tinypng,进行压缩后下载,覆盖本地图片,tinypng是一个强大的图片处理网站,目前最可靠的无损压缩网站. 代码如下: import requests from ...

  7. php 图片压缩并实现苹果图片旋转修复

    用途: 1. 图片压缩,2:通过 extif 插件修复图片旋转(需要php安装extif插件) <?php ini_set("memory_limit","2680 ...

  8. 【PC工具】图片压缩哪家强!tinyPNG图片压缩工具

    不算云服务软件,可能大家最喜欢的应该就是在线(网页)软件了,网页软件功能强大,使用方便,打开浏览器就能用,可以免去软件安装的耗时,也能避免硬盘空间的占用.今天给大家分享一个在线的图片压缩网站:http ...

  9. java 图片压缩100k_如何将图片压缩到100K以内,教你几种免费方法

    一般我们在提交电子证件照时都要求100K以内的图片,超过则无法正常上传,那么有没有免费将图片压缩变小的方法呢?教你3个简单又免费的方法,收藏起来备用吧. 方法1:最简单粗暴的方式就是直接打开图片后用聊 ...

  10. 图片压缩软件_简单易用的图片压缩软件gt;给图片减肥

    正文共816字,预计阅读时间为:3分钟 无论你是设计师 自媒体.办公编辑人员 还是学生 很多时候都会遇到 图片文件体积太大 导致无法上传 或传输太过耗时耗流量的问题 这时我们就需要 一款免费图片压缩工 ...

最新文章

  1. Leetcode 252, 253. Meeting Rooms
  2. “tensorFromBlob”: 不是“at::DeprecatedTypeProperties”的成员
  3. saltstack (1) 简介
  4. C/C++实现读取当前文件夹下的文件-popen
  5. Git之Stash(储藏)备份当前的工作区的内容
  6. mysql查找最大值最小值_查找两个8位数字的最大值| 8086微处理器
  7. $0,$#,$@,$+特殊符号的含义,shell的传递参数
  8. ssh : how to add hostkey to “know_hosts”
  9. MySQL筛选重复数据
  10. 宋宝华_2010年11-12月Linux驱动和内核讲座PPT下载
  11. js Math对象属性和方法
  12. Java——用户激活邮件工具类
  13. VMware虚拟机部署k8s集群
  14. filezilla linux服务器端,FileZilla Server安装配置教程
  15. UML建模工具2021年8-11月更新(共15款)
  16. 4. 木马病毒和免杀技术,另一种免杀思路
  17. mysql 主从ppt_MYSQL主从复制和读写分离.ppt
  18. PTA 数据结构与算法 7-46 新浪微博热门话题
  19. xx:xx,xx:xx规则的字符串怎么解析呢
  20. Activation

热门文章

  1. 除了谷歌,10个细分搜索引擎扩大你的流量池
  2. WIN7中使用c#控制微软拼音输入法
  3. 创蓝253防薅羊毛---风控系统防控原理
  4. java毕业设计地铁舆情管理系统Mybatis+系统+数据库+调试部署
  5. 程序员必备网站,建议收藏!
  6. 华中科技大学计算机系帅哥,华科帅哥为啥没人理?!
  7. 安装mysql 10055_MYSQL无法连接 提示10055错误的解决方法
  8. Idea如何配置CheckStyle
  9. Unity Shader入门精要——第3章 Unity Shader基础
  10. 搭建实验环境时新路由器的常用配置命令