上一篇有提到使用某些EXIF相框/水印工具的時候,會有讀不到CPU鏡頭資料的問題。
所以這篇就來講一下怎麼算鏡頭資訊。
我的環境是Python3.9。
首先,網路上許多Python工具或是教學在抓取EXIF資料的時候,
用的是PIL(Pillow、Python Image Library)這個模組。
from PIL import Image from PIL.ExifTags import TAGS
img = Image.open('DSC01176.JPG') data = img.getexif() all_data = data.get_ifd(0x8769) for tag_id in data: tagname = TAGS.get(tag_id, tag_id) tagcontent = data.get(tag_id) print(f"{tagname}: {tagcontent}") for tag_id in all_data: tagname = TAGS.get(tag_id, tag_id) tagcontent = all_data.get(tag_id) print(f"{tagname}: {tagcontent}")
|
memo
1. 用PIL.ExifTags的TAGS,可以得到tag id對應的tag名稱。
2. 詳細的EXIF資料存在0x8769的位置。
然而,如果我們比對Sony、Canon和Nikon D750的結果,
我們可以看到Nikon的EXIF沒有LensModel這個項目。
(這裡就不放圖片了)
各家廠商甚至各代機身的EXIF內容都不同,
Nikon則是把鏡頭資料寫在MakerNote裡面,
而非把鏡頭「名稱」直接寫在EXIF的LensModel欄位中。
MakerNote混雜了英文和一堆十六進位的數字,
我們要另外decode才可以看到寫了甚麼,
但PIL沒有解讀MakerNote的能力。
不過另一個Python函式庫pyexiv2可以。
import pyexiv2
img = pyexiv2.Image('./DSC_5827.JPG', encoding='big5') all_data = img.read_exif() for key, val in all_data.items(): print(f"{key}: {val}")
|
memo
1. pyexiv2在開啟圖片的時候可以指定編碼,這樣路徑裡就可以包含中文名稱
2. read_exif()回傳的是dict
大概就像這樣,MakerNote的資料變成我們看得懂的格式了。
順帶一提,Nikon不同機身的有不同的MakerNote格式。
能夠解讀MakerNote後,我們就可以用來找鏡頭名稱了。
Nikon的鏡頭名稱可以說是用「算」出來的。
用
LensID
FStop
MinFocalLength
MaxFocalLength
MaxApertureAtMinFocal
MaxApertureAtMaxFocal
MCUVersion
LensType
這八個十六進位數字就可以找到對應的鏡頭名稱。
各種有用的連結和參考資料
1. ExifTool作者整理的EXIF Tags
2. Nikon EXIF Tags
ExifTool其實是個很不錯的工具,作者也有持續在更新各廠牌對應的鏡頭資料
不過他是用Perl寫的,要加在Python程式裡面比較麻煩,我就沒有用
3. 網友整理了Python工具解讀某些品牌LensModel的情況(日文)
4. pyexiv2 Github
原本的pyexiv2在很久很久以前就停止更新了
現在流通的是這個同名的library
因為是對岸網友製作的所以有中文說明可以參考
5. PIL(Pillow) Github
先這樣,之後再慢慢修改