翻譯轉(zhuǎn)自jdhao's blog
前幾天病往,我在工作中遇到了一個奇怪的錯誤捣染。我的同事給了我一些用智能手機拍攝的照片。在他們的計算機上(Windows 7)停巷,所有照片均以橫向模式正確顯示耍攘。但是,當我查看這些照片時畔勤,發(fā)現(xiàn)其中一些照片是以縱向模式(旋轉(zhuǎn)90或270度)或上下顛倒(旋轉(zhuǎn)180度)顯示的蕾各。
我很好奇發(fā)生了什么,并了解了 Exif及其所有相關(guān)內(nèi)容硼被。
Exif定向如何工作
什么是Exif
Exif(可交換圖像文件格式)是一種協(xié)議,用于存儲有關(guān)數(shù)碼相機拍攝的圖像的各種元信息渗磅。Exif與實際圖像數(shù)據(jù)一起存儲嚷硫。Exif中的一些元信息包括相機制造商,快門速度始鱼,焦距仔掸,方向,拍攝時間等医清。這些元信息稱為標簽起暮,每個標簽都有一個由Exif格式標準決定的特定標簽號。標簽的完整列表及其相關(guān)信息可在此處找到会烙。
Exif方向標志
在這里负懦,我們對方向元信息感興趣筒捺。用相機拍攝照片時,可能并不總是將相機保持在相機頂部與場景頂部相對應(yīng)的位置纸厉。該博客下面的圖片 清楚地說明了這個想法:
但是系吭,無論如何握持相機,如果您在計算機上查看圖像颗品,圖像都將以正確的方向顯示肯尺。這與Exif方向標志有關(guān)。當您以非直立姿勢握持相機時躯枢,所拍攝的原始照片將存儲為旋轉(zhuǎn)圖像则吟。數(shù)字設(shè)備(可以是智能手機或數(shù)碼相機)具有傳感器,可以記錄相機的方向锄蹂,并將該信息寫入Exif中的方向標志氓仲。
Exif方向標記可以具有1到9 的9個不同值。下圖顯示了其中的八個:
通常败匹,對于數(shù)碼照片寨昙,您只會獲得標志1、8掀亩、3舔哪、6。標志2槽棍、7捉蚤、4、5代表鏡像和旋轉(zhuǎn)的圖像版本炼七。
為什么我的圖像顯示錯誤缆巧?
當您使用照片查看器檢查計算機上的圖像時,如果照片查看器可以讀取Exif信息并尊重該信息豌拙,它將基于方向信息自動旋轉(zhuǎn)原始圖像陕悬。最終結(jié)果是,無論實際存儲方式如何按傅,您都可以看到方向正確的照片捉超。
現(xiàn)在在本文開頭討論這個問題。根據(jù) 本文唯绍,Windows 8之前的Windows系統(tǒng)不會考慮Exif方向標志并按原樣顯示圖像拼岳,即,顯示原始的未旋轉(zhuǎn)圖像况芒,而不是正確旋轉(zhuǎn)的圖像惜纸。由于同事們給我的圖像可以在Windows 7計算機上正確顯示,因此我們可以得出結(jié)論,原始圖像的方向正確耐版。不知何故祠够,智能手機為某些照片報告了錯誤的方向標記。當我在Windows 10機器上顯示這些照片時椭更,由于Windows 10遵循方向標記哪审,由于錯誤的方向標記,某些圖像將顯示為旋轉(zhuǎn)虑瀑。
另一方面湿滓,如果您在Windows 10上看到正確的照片但在Windows 7機器上旋轉(zhuǎn)了一張照片,那是因為原始圖像處于旋轉(zhuǎn)位置舌狗,并且Windows 7不遵守Exif中的方向信息叽奥。
讀取和寫入Exif信息
IrfanView
IrfanView是Windows上出色的圖像查看器,它尊重圖像Exif信息痛侍。要查看圖像Exif信息朝氓,請打開圖像,然后單擊Image -> Information
主届。如果圖像包含Exif信息赵哲,則可以單擊EXIF info
彈出窗口左下方的按鈕以檢查圖像Exif信息。
禁用IrfanView的自動旋轉(zhuǎn)
默認情況下君丁,IrfanView會遵守Exif信息枫夺,并將根據(jù)其方向標記自動旋轉(zhuǎn)圖像。要禁用此行為绘闷,請轉(zhuǎn)到Options -> Properties/Settings
橡庞,單擊JPG/PCD/GIF
并取消選中該框Auto-rotate image according to EXIF info (if available)
。
Pillow和Exif信息
如果您使用Pillow讀取圖像并顯示或再次保存印蔗,則Pillow將不遵守Exif方向標簽扒最。您可能在這里 和這里看到這樣的問題。有一個 拉取請求可以解決此問題华嘹,該請求現(xiàn)已合并吧趣。
Pillow能夠讀取圖像的Exif信息,但無法編輯Exif信息耙厚。下面顯示了顯示圖像Exif信息的示例腳本:
from PIL import Image
from PIL. from PIL.ExifTags import TAGS
img = Image.open('test.jpg')
exif = img.getexif()
for k, v in exif.items():
print('{}: {}'.format(TAGS[k], v))
在上面的腳本中强挫,我們使用 Image.getexif()
3檢索圖像Exif信息。 TAGS
是將標簽號映射到描述性名稱的詞典颜曾。
Piexif
Python程序包piexif可用于讀取和寫入圖像Exif信息纠拔。
基于 其文檔站點上的 示例秉剑,我展示了一個更改圖像Exif方向標記并使用新的Exif信息保存新圖像的示例泛豪。
from PIL import Image
import piexif
img = Image.open('test.jpg')
if "exif" in img.info:
exif_dict = piexif.load(img.info['exif'])
if piexif.ImageIFD.Orientation in exif_dict['0th']:
exif_dict['0th'][pixeif.ImageIFD.Orientation] = 3
# quick and dirty work around to avoid type error
exif_dict['Exif'][41729] = b'1'
exif_bytes = piexif.dump(exif_dict)
img.save('new_img.jpg', exif=exif_bytes)
Exif的主要信息存儲在的0th
鍵中exif_dict
,該鍵也是Python字典。似乎piexif并未檢查Exif dict的值類型诡曙,因此 當我們嘗試轉(zhuǎn)儲exif_dict時可能會 遇到ValueError臀叙。閱讀piexif的源代碼之后,我現(xiàn)在使用下面的代碼行來解決此問題价卤。
exif_dict['Exif'][41729] = b'1'
之后劝萤,您應(yīng)該能夠正確地轉(zhuǎn)儲exif_dict
。