在我们拍的照片以及各类图像文件中,其实还保存着一些信息是无法直观看到的,比如手机拍照时会有的位置信息,图片的类型、大小等,这些信息就称为 EXIF 信息。一般 JPG 、 TIFF 这类的图片文件都会有这样的信息。EXIF 其实就是专门为这种数码照片所定制的,专门用于记录数码照片的属性信息和拍摄数据的,最初由日本制定。这个其实很好理解,日本对相机行业基本是垄断般的存在,所以这类的标准当然就是由他们制定啦!

EXIF 在 Windows 系统中具有原生的支持,鼠标右键点击图片打开菜单,然后点击属性并切换到详细信息就可以直接看到图片文件的 EXIF 信息了。由于这些信息是可以被随意编辑的,所以它们可以作为一些参考,并不能作为某些功能属性的确定值来获取,比如宽高这些信息就不要完全相信 EXIF 中的。

获取 EXIF 中的图片类型信息

首先,我们看下通过 EXIF 来查看图片的类型。

var_dump(exif_imagetype($png)); // int(3)
echo exif_imagetype($png) == IMAGETYPE_PNG ? $png . '是 PNG 图片' : $png . '不是 PNG 图片', PHP_EOL;
// ../img/1.png是 PNG 图片 var_dump(exif_imagetype($jpg)); // int(2)
echo exif_imagetype($jpg) == IMAGETYPE_JPEG ? $jpg . '是 jpg 图片' : $jpg . '不是 JPG 图片', PHP_EOL;
// ../img/2.jpg是 jpg 图片

直接使用 exif_imagetype() 函数就会返回一个图片类型的常量,也就是以 IMAGETYPE_ 开头的常量信息所代表的图片类型。它还包括其它很多类型,这里只是演示了我们平常最常见的 jpg 和 png 类型的图片类型的获取。

它和 getimagesize() 函数返回的第三个属性,也就是下标为 2 的那个属性的内容是一样的,在 getimagesize() 函数中,0 和 1 代表的是宽高,2 代表的就是图片的类型。

var_dump(getimagesize($jpg));
// array(7) {
// [0]=>
// int(300)
// [1]=>
// int(244)
// [2]=>
// int(2)
// [3]=>
// string(24) "width="300" height="244""
// ["bits"]=>
// int(8)
// ["channels"]=>
// int(3)
// ["mime"]=>
// string(10) "image/jpeg"
// }

获取完整的 EXIF 信息

图片中完整的所有 EXIF 信息是通过 exif_read_data() 函数来获取的。

var_dump(exif_read_data($png));
// PHP Warning: exif_read_data(1.png): File not supported in /Users/zhangyue/MyDoc/博客文章/dev-blog/php/202011/source/11.使用PHP获取图像文件的EXIF信息.php on line 14 // Warning: exif_read_data(1.png): File not supported in /Users/zhangyue/MyDoc/博客文章/dev-blog/php/202011/source/11.使用PHP获取图像文件的EXIF信息.php on line 14 // bool(false) var_dump(exif_read_data($jpg));
// array(8) {
// ["FileName"]=>
// string(5) "2.jpg"
// ["FileDateTime"]=>
// int(1605061174)
// ["FileSize"]=>
// int(19075)
// ["FileType"]=>
// int(2)
// ……
// ……

就像前面讲过的,EXIF 信息只在 JPG 、 TIFF 等类型的图片格式中存在,所以 PNG 图片是无法获取到 EXIF 信息的。如果对 PNG 图片使用 exif_read_data() 就会报出警告。而对于 JPG 来说,就会返回完整的全部的 EXIF 内容。这里我们只截取了一部分,本身的内容非常多,不只是宽、高、类型、压缩比率之类的,如果是手机拍摄的还能看到手机厂商、地理位置、快门参数、光圈参数等,当然,这个也和你使用的相机有很大的关系,有的厂家可能就会少一些数据。这个大家可以自己拍张照然后使用这个函数来自己查看一下。

另外,还有一个别名函数 read_exif_data() ,与 exif_read_data() 的功能是类似的,就是它的一个别名,并且在 PHP7 以后就已经标记为过时的语法了。大家可以了解一下。

var_dump(read_exif_data($jpg));
// PHP Deprecated: Function read_exif_data() is deprecated in /Users/zhangyue/MyDoc/博客文章/dev-blog/php/202011/source/11.使用PHP获取图像文件的EXIF信息.php on line 17 // Deprecated: Function read_exif_data() is deprecated in /Users/zhangyue/MyDoc/博客文章/dev-blog/php/202011/source/11.使用PHP获取图像文件的EXIF信息.php on line 17
// array(8) {
// ["FileName"]=>
// string(5) "2.jpg"
// ["FileDateTime"]=>
// int(1605061174)
// ["FileSize"]=>
// ……
// ……

获取指定索引的头名称

索引头对应的就是 EXIF 中的字段名称,我们可以查看当前所有支持的索引头信息,内容非常多。也可以根据索引头获得属性名称,然后再到 EXIF 中查找对应的属性信息。

echo "256: " . exif_tagname(256) . PHP_EOL;
// 256: ImageWidth
for ($id = 1; $id <= 65535; $id++) {
if (exif_tagname($id) != "") {
echo $id . ' ( ' . exif_tagname($id) . ' )', PHP_EOL;
}
}
// 11 ( ACDComment )
// 254 ( NewSubFile )
// 255 ( SubFile )
// 256 ( ImageWidth )
// 257 ( ImageLength )
// 258 ( BitsPerSample )
// 259 ( Compression )
// ……
// ……
// ……

读取 JPG 文件中嵌入的缩略图

可能很多人不知道吧,EXIF 中是可以保存一个缩略图的。而且大家的手机拍出来的相片基本都会有这个缩略图存在。Windows 系统中如果图片有缩略图的话也会直接用 EXIF 中的缩略图,如果没有的话,就会自动在目录中生成一个 Thumbs.db 文件,也就是一个缩略图的数据库。

var_dump(exif_thumbnail('../img/3.jpeg'));
// string(14369) "����� // !"$��@"��� // }!1AQa"q2��#B��R��$3br�
// %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz������������������������������������������������������������������������� // w!1AQaq"2B���� #3R�br�
// $4�%�&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz��������������������������������������������������������������������������
// ?�b�������������?J�l�2 file_put_contents('../img/3-thumbnail.jpeg', exif_thumbnail('../img/3.jpeg'));

在 PHP 中可以通过 exif_thumbnail() 这个函数直接获取 JPG 文件中 EXIF 里面保存的缩略图信息。在测试代码中我们获取到后再将它保存为正式的图片,大家就可以看到缩略图的真实样子了。并且我们使用 exif_read_data() 来读取这个文件的话,也能看到缩略图保存的信息。

var_dump(exif_read_data('../img/3.jpeg'));
// array(56) {
// ……
// ……
// ……
// ["Make"]=>
// string(6) "Xiaomi"
// ["THUMBNAIL"]=>
// array(9) {
// ["JPEGInterchangeFormat"]=>
// int(5504)
// ["Orientation"]=>
// int(6)
// ["JPEGInterchangeFormatLength"]=>
// int(14369)
// ["Compression"]=>
// int(6)
// ["ResolutionUnit"]=>
// int(2)
// ["XResolution"]=>
// string(4) "72/1"
// ["YResolution"]=>
// string(4) "72/1"
// ["ExifImageLength"]=>
// int(240)
// ["ExifImageWidth"]=>
// int(320)
// }
// ["UndefinedTag:0x9AAA"]=>
// string(4480) "1y�L�=w%�s_�&��v��oJ��$Gdz|d�9n�
// �������~��+9����2V:+�о�Qn]�۲͐� ��U��nwF��w;f�h�k���i*w�bd+�D0�=\o��y����x\�,��BS��#/d�9���˓
// ,%C�3���eIZ~��������oLܰܡ~�}#�y:4Ӥ}� ��dȻGI*Y��
// ��m�)��x#a�6J<���2�z�B3���2�Ol*8
// w W�"E�c���OV�l9���� p�f�����KAFUg���<I���ʯ9E�S�
// ����U�ޘ�CO�>ʈ7��ݪG�T&,� Ie�%� // ?��S���§�9��6s��8LT&o
// Vn�Џ�R��c6��Ϝ p�G�f#��/�o����_�@�$�%#
// � �Ҡ��5v��~����Ȣ)�ڽa�i�:���\�}��3xKM�CIe�����5&�/��䇃�隙R�+��He��}���b�Ґ�?
// ……
// ……
// ……

总结

对于图片的 EXIF 有了一个基本的了解了吧。今天学习的需要注意的几点是:一是 EXIF 只有 JPG 、 TIFF 这类的图片格式上才有,二是它们是可修改的,三是这玩意里面竟然还能保存一张缩略图。果然,学习就是个无底洞,一不小心又开了眼界了。加油吧,少年们!

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202011/source/11.使用PHP获取图像文件的EXIF信息.php

参考文档:

https://www.php.net/manual/zh/book.exif.php

https://baike.baidu.com/item/Exif/422825?fr=aladdin

http://www.360doc.com/content/13/0223/14/9290626_267432131.shtml

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

使用PHP获取图像文件的EXIF信息的更多相关文章

  1. C# 获取图片的EXIF 信息

    关于 EXIF 信息的介绍. 1  EXIF,是英文Exchangeable Image File(可交换图像文件)的缩写.EXIF是一种图像文件格式,只是文件的后缀名为jpg.EXIF信息是由数码相 ...

  2. 获取图片的EXIF信息

    对于专业的摄影师来说,Exif信息是很重要的信息,也包含了非常多的东西 1.EXIF EXIF(Exchangeable Image File)是“可交换图像文件”的缩写,当中包含了专门为数码相机的照 ...

  3. 利用php获取图片完整Exif信息类 获取图片详细完整信息类

    <?php /** * @Author: TonyLevid * @Copyright: TonyLevid.com * @Name: Image Exif Class * @Version: ...

  4. 用python 获取照片的Exif 信息(获取拍摄设备,时间,地点等信息)

    第一步:先安装 pip install exifread 第二部:上代码 import exifread import requests class PhotoExifInfo(): def __in ...

  5. 以最省内存的方式把大图片加载到内存及获取Exif信息和获取屏幕高度和宽度的新方法

    我们在加载图片时经常会遇到内存溢出的问题,图片太大,我们加载图片时,一般都是用的如下一般方法(加载本地图片): /** * 不作处理,去加载图片的方法,碰到比较大的图片会内存溢出 */ private ...

  6. 七牛--关于图片上传方向不统一的问题--主要关于图片EXIF信息中旋转参数Orientation的理解

    [图片引用方向纠正]直接在图片后面添加 ?imageMogr/auto-orient eg:http://data.upfitapp.com/data/2016/10/18/1629114767606 ...

  7. 七牛:关于图片 EXIF 信息中旋转参数 Orientation 的理解

    EXIF(Exchangeable Image File)是 “可交换图像文件” 的缩写,当中包含了专门为数码相机的照片而定制的元数据,可以记录数码照片的拍摄参数.缩略图及其他属性信息,简单来说,Ex ...

  8. 图片Exif信息

    Exif文件格式简述链接:https://www.zhihu.com/question/23727439/answer/25467748 可交换图像文件常被简称为Exif(Exchangeable i ...

  9. IOS: 使用imageIO获取和修改图片的exif信息

    使用imageIO获取和修改图片的exif信息 一幅图片除了包含我们能看见的像素信息,背后还包含了拍摄时间,光圈大小,曝光等信息.UIImage类将这些细节信息都隐藏了起来,只提供我们关心的图片尺寸, ...

随机推荐

  1. Linux下的USB总线驱动(一)

    版权所有,转载请说明转自 http://my.csdn.net/weiqing1981127 一.USB理论 1.      USB概念概述 USB1.0版本速度1.5Mbps(低速USB) USB1 ...

  2. 泛微OA e-cology 数据库接口信息泄露学习

    泛微OA e-cology 数据库接口信息泄露 漏洞信息 攻击者可通过存在漏洞的页面直接获取到数据库配置信息.如果攻击者可直接访问数据库,则可直接获取用户数据,甚至可以直接控制数据库服务器:会将当前连 ...

  3. Proteus仿真—51单片机实现AC信号测频、显示、双机通信

    文章目录 一.原理图部分 二.源码部分 单片机1 单片机2 在Proteus仿真软件里面使用STC89C52实现指定频率的AC信号的测频.显示.双机通信. 一.原理图部分 整体的电路图如示: DC-A ...

  4. noip29

    T1 以下的LIS代指最长不降子序列. 考场看到取模,便想到了之前写过的Medain,取模操作让序列分布均匀,对应到本题上,既然是求LIS,那它应该是有循环节的,后来打表证实确实是有. 然后,我码了个 ...

  5. NOIP 模拟 $22\; \rm d$

    题解 很好的贪心题 考虑去掉的矩形一定是几个 \(a\) 最小的,几个 \(b\) 最小的,枚举去掉几个 \(a\),剩下的去掉 \(b\) 先对 \(a\) 排序,用小根堆维护 \(b\) ,记录哪 ...

  6. Windows系统搭建Redis集群三种模式(零坑、最新版)

    目录 主从复制 修改配置文件 启动各节点 验证 哨兵模式 修改配置文件 启动实例 验证 集群模式 修改配置文件 启动实例 验证 主从复制 新建以下三个目录,用来部署一主二从 redis 的安装在另外一 ...

  7. 深入研究webpack之Tree Shaking相关属性sideEffects用处

    Tree Shaking我原来也只是了解,这次碰巧深入研究了下,就写个博客记录一下,网上有很多讲Tree Shaking的,我写的这篇跟他们侧重点不一样 Tree Shaking相关的基础知识 1 w ...

  8. jdbc操作mysql(四):利用反射封装

    前言 有了前面利用注解拼接sql语句,下面来看一下利用反射获取类的属性和方法 不过好像有一个问题,数据库中的表名和字段中带有下划线该如何解决呢 实践操作 工具类:获取connection对象 publ ...

  9. python json demo

    值得注意的一点是,list类型的数据可以用[2,3]的方式定义,如"b" import json jsonData = '{"a":1,"b" ...

  10. linux shell 删除满足正则表达式的文件

    用find配合xargs rm find . -type f -name "to_delete_file_[a-z]_*_[0-9].jpg" | xargs rm