【51CTO.com快译】如果大家的工作涉及处理计算机图像,那么总有一天会遇到文件损坏这类问题。我个人经常处理动画渲染工作(请注意,***的渲染方式是对图像文章进行按序渲染,而非一次性处理视频文件),所以这类问题真的经常造成困扰。另外,摄影师甚至是普通用户在处理计算机图像时,也往往会遇到色调映射及文件传输过程造成的图像损坏。
事实上,修复或者替换受损图像本身并不困难,通常只需要大家重新渲染图像或者再次尝试传输。其核心问题在于如何尽早找出那些受损图像。这类问题被发现的时间点越晚,给您造成的麻烦就越大。
那么我们该如何解决?最直观的办法无疑是不断打开文件,若其发生损坏则相关图像编辑器或者查看器即会报错。然而当图像数量极大时,单单是浏览一遍图像就可能耗费数小时甚至数天时间。虽然动画渲染处理的文件通常体积较小,但数量却相当惊人。我个人经常需要渲染超过44000帧图像,由此带来的审查工作量可想而知。
那么该如何解决?答案很简单——编写脚本。
首先,列出要检查的文件。假定要检查的所有图像文件皆处于硬盘上的单一目录内,另外假设大家会立足于此目录运行脚本,则可使用以下Python代码获取对应文件列表:
import os for filename in os.listdir('./'): print(filename)
如果愿意,大家也可以进一步缩小图像列表(或者更为明确地进行说明,例如不会将脚本本身作为其中一个文件),具体方式为添加PNG扩展名:
import os for filename in os.listdir('./'): if filename.endswith('.png'): print(filename)
现在您已经拥有当前工作目录内各PNG图像文件的列表了。接下来弄清哪些图像已经受损。遗憾的是,目前我们还很难在不配合图像处理功能的情况下直接判断其是否受损,这意味着大家需要首先获取图像处理模块以查看这些文件。但好消息是,Python开发社区提供了现成的解决方案。
事实上,大家可以直接安装完整的软件包库。这里我推荐pip(Python软件包的推荐安装工具)。在大多数平台上,其都会在您安装Python时被默认一同安装。
备注:我个人使用Python 3,但如果大家使用Python 2,那么本文内容会因版本差异而需要进行调整。另外,很多Linux发行版会建议大家安装自己的软件包管理系统。这里之所以推荐pip,是因为其能够在全部支持Python运行的平台上提供相同的助益。
这里我还建议大家安装Pillow这款软件包。其属于PIL(Python图像库)的一款友好型fork,适用于现有Python 3与Python 2。要安装Pillow,您只需要在终端窗口内输入pip install Pillow即可。这套Python软件包工具随后会自行搞定其它工作。
安装完成后,接下来是将其运用至脚本当中。其使用方式与Python中的其它模块相同,您可使用import实现——在本示例中,您可使用import PIL。不过要找到受损图像,大家并不需要将Pillow库全部导入脚本。在Python中,大家可以只导入模块中的某一子组件。这种作法能够有效降低内存占用率,更重要的是从起点阶段即明确自己的脚本需要哪些功能。另外,在导入子组件时,您的脚本所需要的输入内容也更少,即能够简化整个使用过程。
要导入模块中的子组件,大家可以将import与from指令相配合。在Pillow中,大家的脚本只需要使用Image类,因此可以使用from PIL import Image这样的表达。事实上,您完全能够利用os模块实现同样的效果。这意味着我们可以将import os调整为from os import listdir,这意味着当运行此脚本时,将不再需要输入os.listdir。相反,大家只需要输入listdir,即可完成全部必要导入。
总结起来,现在我们的脚本应如下所示:
from os import listdir from PIL import Image for filename in listdir('./'): if filename.endswith('.png'): print(filename)
虽然图像已经加载完成,但脚本并未对其进行任何处理。现在开始讨论脚本的功能部分。很明显,我们需要打开每个图像文件并检查其是否可读。如果存在错误,则意味着发现了一个受损文件。要实现这一功能,大家可以使用try/except代码块。简言之,您的脚本会尝试运行一条函数以打开文件。如果该函数返回错误,即属于exception,则代表图像出了问题。具体而言,该项例外属于IOError或者SyntaxError类型,则代表图像受损。
实现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>
为了找到受损图像文件,大家还需要测试两项函数: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
全部完成!将此脚本保存在您的图像文件目录内,运行后即可得到一份包含全部受损图像文件的列表。如果没有任何输出结果,则证明所有图像文件皆未损坏。
就是这么简单,希望大家能够享受脚本编写与其运行效果带来的乐趣!
原文标题:Using Python to find corrupted images,原文作者:Jason van Gumster
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】