如何利用Python找出損壞的圖像?
譯文【51CTO.com快譯】如果大家的工作涉及處理計算機圖像,那么總有一天會遇到文件損壞這類問題。我個人經(jīng)常處理動畫渲染工作(請注意,***的渲染方式是對圖像文章進行按序渲染,而非一次性處理視頻文件),所以這類問題真的經(jīng)常造成困擾。另外,攝影師甚至是普通用戶在處理計算機圖像時,也往往會遇到色調(diào)映射及文件傳輸過程造成的圖像損壞。
事實上,修復或者替換受損圖像本身并不困難,通常只需要大家重新渲染圖像或者再次嘗試傳輸。其核心問題在于如何盡早找出那些受損圖像。這類問題被發(fā)現(xiàn)的時間點越晚,給您造成的麻煩就越大。
那么我們該如何解決?最直觀的辦法無疑是不斷打開文件,若其發(fā)生損壞則相關圖像編輯器或者查看器即會報錯。然而當圖像數(shù)量極大時,單單是瀏覽一遍圖像就可能耗費數(shù)小時甚至數(shù)天時間。雖然動畫渲染處理的文件通常體積較小,但數(shù)量卻相當驚人。我個人經(jīng)常需要渲染超過44000幀圖像,由此帶來的審查工作量可想而知。
那么該如何解決?答案很簡單——編寫腳本。
首先,列出要檢查的文件。假定要檢查的所有圖像文件皆處于硬盤上的單一目錄內(nèi),另外假設大家會立足于此目錄運行腳本,則可使用以下Python代碼獲取對應文件列表:
import os for filename in os.listdir('./'): print(filename)
如果愿意,大家也可以進一步縮小圖像列表(或者更為明確地進行說明,例如不會將腳本本身作為其中一個文件),具體方式為添加PNG擴展名:
import os for filename in os.listdir('./'): if filename.endswith('.png'): print(filename)
現(xiàn)在您已經(jīng)擁有當前工作目錄內(nèi)各PNG圖像文件的列表了。接下來弄清哪些圖像已經(jīng)受損。遺憾的是,目前我們還很難在不配合圖像處理功能的情況下直接判斷其是否受損,這意味著大家需要首先獲取圖像處理模塊以查看這些文件。但好消息是,Python開發(fā)社區(qū)提供了現(xiàn)成的解決方案。
事實上,大家可以直接安裝完整的軟件包庫。這里我推薦pip(Python軟件包的推薦安裝工具)。在大多數(shù)平臺上,其都會在您安裝Python時被默認一同安裝。
備注:我個人使用Python 3,但如果大家使用Python 2,那么本文內(nèi)容會因版本差異而需要進行調(diào)整。另外,很多Linux發(fā)行版會建議大家安裝自己的軟件包管理系統(tǒng)。這里之所以推薦pip,是因為其能夠在全部支持Python運行的平臺上提供相同的助益。
這里我還建議大家安裝Pillow這款軟件包。其屬于PIL(Python圖像庫)的一款友好型fork,適用于現(xiàn)有Python 3與Python 2。要安裝Pillow,您只需要在終端窗口內(nèi)輸入pip install Pillow即可。這套Python軟件包工具隨后會自行搞定其它工作。
安裝完成后,接下來是將其運用至腳本當中。其使用方式與Python中的其它模塊相同,您可使用import實現(xiàn)——在本示例中,您可使用import PIL。不過要找到受損圖像,大家并不需要將Pillow庫全部導入腳本。在Python中,大家可以只導入模塊中的某一子組件。這種作法能夠有效降低內(nèi)存占用率,更重要的是從起點階段即明確自己的腳本需要哪些功能。另外,在導入子組件時,您的腳本所需要的輸入內(nèi)容也更少,即能夠簡化整個使用過程。
要導入模塊中的子組件,大家可以將import與from指令相配合。在Pillow中,大家的腳本只需要使用Image類,因此可以使用from PIL import Image這樣的表達。事實上,您完全能夠利用os模塊實現(xiàn)同樣的效果。這意味著我們可以將import os調(diào)整為from os import listdir,這意味著當運行此腳本時,將不再需要輸入os.listdir。相反,大家只需要輸入listdir,即可完成全部必要導入。
總結起來,現(xiàn)在我們的腳本應如下所示:
from os import listdir from PIL import Image for filename in listdir('./'): if filename.endswith('.png'): print(filename)
雖然圖像已經(jīng)加載完成,但腳本并未對其進行任何處理?,F(xiàn)在開始討論腳本的功能部分。很明顯,我們需要打開每個圖像文件并檢查其是否可讀。如果存在錯誤,則意味著發(fā)現(xiàn)了一個受損文件。要實現(xiàn)這一功能,大家可以使用try/except代碼塊。簡言之,您的腳本會嘗試運行一條函數(shù)以打開文件。如果該函數(shù)返回錯誤,即屬于exception,則代表圖像出了問題。具體而言,該項例外屬于IOError或者SyntaxError類型,則代表圖像受損。
實現(xiàn)try/except的語法非常簡單,如下所示:
try: # These next functions may produce an exception # <some function> except (IOError, SyntaxError) as e: # These are the exceptions we're looking for # <do something... like print an intelligent error message>
為了找到受損圖像文件,大家還需要測試兩項函數(shù):Image.open( )與verify( )。如果將其打包進try/except代碼塊,則最終腳本如下所示:
from os import listdir from PIL import Image for filename in listdir('./'): if filename.endswith('.png'): try: img = Image.open('./'+filename) # open the image file img.verify() # verify that it is, in fact an image except (IOError, SyntaxError) as e: print('Bad file:', filename) # print out the names of corrupt files
全部完成!將此腳本保存在您的圖像文件目錄內(nèi),運行后即可得到一份包含全部受損圖像文件的列表。如果沒有任何輸出結果,則證明所有圖像文件皆未損壞。
就是這么簡單,希望大家能夠享受腳本編寫與其運行效果帶來的樂趣!
原文標題:Using Python to find corrupted images,原文作者:Jason van Gumster
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】