在我們拍的照片以及各類影像檔案中,其實還保存著一些資訊是無法直觀看到的,比如手機拍照時會有的位置資訊,圖片的型別、大小等,這些資訊就稱為 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/296000.html
標籤:PHP
