有谁知道检查图形文件(特别是 JPEG、GIF 和 PNG)是否损坏的方法(最好以自动化方式)?
解释:
几天前,一个命令运行错误,最终删除了 FAT32 卷中数千个图形文件,而该卷实际上已经没有空间了。我使用过几种不同的文件/照片恢复程序,但它们的恢复量自然是有限的(不过幸运的是,该卷有 8KB 簇,这多少有点帮助)。
无论如何,一些较大的文件,即碎片化的文件,现在已经损坏。其中一些甚至根本不是真正的文件(恢复软件只是转储了现在被覆盖的目录条目指向的簇),而另一些文件则因碎片化而损坏。
此外,由于某些图片格式将较小版本的图片嵌入为缩略图,因此扫描缩略图以查找损坏并不可靠,因为它可能是完整的,而实际文件(即全尺寸查看的图片)可能已损坏。
以下是几个示例:
这是第二张。它已经损坏得什么都显示不出来。
(第三个甚至不会上传因为它甚至没有正确的标题!)
答案1
因为我在尝试回答同样的问题时偶然发现了这一点,所以我将添加我发现的另一个很好的解决方案:
坏佩吉
用法
从菜单中选择File > Scan
,然后使用文件对话框浏览到图像所在的文件夹。然后程序将开始扫描文件夹和所有子文件夹中的图像(.jpg、.png、.bmp、.gif)。如果您想扫描大量图片,这将需要一些时间,因为程序需要完全加载和解析图像文件,因此您可能需要让它运行一整夜。
扫描时,状态栏中会显示进度百分比。它发现的任何不完美的图像都会直接显示在列表中。如果您单击列表中的任何图像,它将显示图像的预览。通常,图像的文件格式只会有小问题,图像仍然看起来不错。其他时候,图像根本不会呈现,预览将只是黑色。有时图像会损坏,您会看到类似上面屏幕截图的内容。
一个非常方便的技巧是单击列标题Reason
,然后图像将根据损坏的严重程度进行排序(例如,所有仍然正确呈现的错误文件格式将移至底部,让您专注于更严重的情况)。
此外,如果第一次扫描已完成,您开始另一次扫描,结果将直接添加到列表中。因此,如果您有许多包含图像的不同文件夹,您可以简单地按顺序扫描它们,而不会在开始新扫描时清除列表。如果您确实希望清除列表,请使用上下文菜单并单击Clear list
。
链接
可在此处找到适用于 Windows、Linux 和 OS X 的下载:
https://www.coderslagoon.com
答案2
尝试jpeg信息' -c
' 选项适用于您的 JPEG 文件。
我也见过你展示的损坏情况发生在坏的存储卡上。
你想要的应该是可能的和可用的,检查一下图形文件损坏;
在线部分图形文件格式百科全书。
另请参阅文件完整性检查在基本介绍巴布亚新几内亚特征。
您可能对这个 Stackoverflow 问题感兴趣,
如何以编程方式检查图像(PNG、JPEG 或 GIF)是否损坏?
答案3
ImageMagick 的标识程序会告诉您图像是否损坏。使用“for i in find”循环测试来自identify的非0返回代码可以让您轻松编写测试脚本以转储损坏或损坏的文件列表。它也适用于带有PowerShell的Windows。
以下代码对路径进行了更改,在 powershell 中运行良好
$stream = [System.IO.StreamWriter] "corrupt_jpegs.txt"
get-childitem "c:\" -include *.jpg -recurse | foreach ($_) {
& "C:\Program Files\ImageMagick-6.7.1-Q16\identify.exe" $_.fullname > $null
if($LastExitCode -ne 0){
$stream.writeline($_.fullname)
}
}
$stream.close()
答案4
我已经修改了来自 galacticninja 答案的代码完全按照 OP 的要求执行。它以相同的方式运行,但是它会将文件移动到根C:\
目录中的 catch 文件夹,而不是仅在命令提示符上列出图像。
你可以找到我修改后的代码在 Pastebin 上或以下:
#This program will scan a directory and all it's subdirectories for corrupted jpg, png, gif, and bmp images and collect them in a Catch folder
#To run this program you will need to install Python 2.7 and PILLOW
#Once installed save this file in a notepad document with the .py extension
#Than run cmd.exe and type the following: C:\Python27\python.exe "C:\Directory this is saved in\this.py" "C:\Directory to be scanned"
#You must make a folder called Catch in your root C:\ directory for the corrupted images to be collected in
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# vi:ts=4 sw=4 et
# Okay, this code is a bit ugly, with a few "anti-patterns" and "code smell".
# But it works and I don't want to refactor it *right now*.
# TODO:
# * Refactor it a little
# * Add support for custom filename filter (instead of the hardcoded one)
#Big thanks to denilsonsa for writing most of this code at https://bitbucket.org/denilsonsa/small_scripts/src/542edd54d290d476603e939027ca654b25487d85/jpeg_corrupt.py?at=default
import getopt
import fnmatch
import re
import os
import os.path
import sys
import PIL.Image
available_parameters = [
("h", "help", "Print help"),
("v", "verbose", "Also print clean files"),
]
class ProgramOptions(object):
"""Holds the program options, after they are parsed by parse_options()"""
def __init__(self):
self.globs = ['*.jpg', '*.jpe', '*.jpeg', '*.gif', '*.png', '*.bmp']
self.glob_re = re.compile('|'.join(
fnmatch.translate(g) for g in self.globs
), re.IGNORECASE)
self.verbose = False
self.args = []
def print_help():
global opt
scriptname = os.path.basename(sys.argv[0])
print "Usage: {0} [options] files_or_directories".format(scriptname)
print "Recursively checks for corrupt image files"
print ""
print "Options:"
long_length = 2 + max(len(long) for x,long,y in available_parameters)
for short, long, desc in available_parameters:
if short and long:
comma = ", "
else:
comma = " "
if short == "":
short = " "
else:
short = "-" + short[0]
if long:
long = "--" + long
print " {0}{1}{2:{3}} {4}".format(short,comma,long,long_length, desc)
print ""
print "Currently (it is hardcoded), it only checks for these files:"
print " " + " ".join(opt.globs)
def parse_options(argv, opt):
"""argv should be sys.argv[1:]
opt should be an instance of ProgramOptions()"""
try:
opts, args = getopt.getopt(
argv,
"".join(short for short,x,y in available_parameters),
[long for x,long,y in available_parameters]
)
except getopt.GetoptError as e:
print str(e)
print "Use --help for usage instructions."
sys.exit(2)
for o,v in opts:
if o in ("-h", "--help"):
print_help()
sys.exit(0)
elif o in ("-v", "--verbose"):
opt.verbose = True
else:
print "Invalid parameter: {0}".format(o)
print "Use --help for usage instructions."
sys.exit(2)
opt.args = args
if len(args) == 0:
print "Missing filename"
print "Use --help for usage instructions."
sys.exit(2)
def is_corrupt(imagefile):
"""Returns None if the file is okay, returns an error string if the file is corrupt."""
#http://stackoverflow.com/questions/1401527/how-do-i-programmatically-check-whether-an-image-png-jpeg-or-gif-is-corrupted/1401565#1401565
try:
im = PIL.Image.open(imagefile)
im.verify()
except Exception as e:
return str(e)
return None
def check_files(files):
"""Receives a list of files and check each one."""
global opt
i = 0
for f in files:
# Filtering JPEG, GIF, PNG, and BMP images
i=i+1
if opt.glob_re.match(f):
status = is_corrupt(f)
if opt.verbose and status is None:
status = "Ok"
if status:
file = "{0}".format(f, status)
print file
shorthand = file.rsplit('\\', 1)
extention =shorthand[1]
fullFileName = "C:\Catch" + "\\" + extention
os.rename(file, fullFileName)
def main():
global opt
opt = ProgramOptions()
parse_options(sys.argv[1:], opt)
for pathname in opt.args:
if os.path.isfile(pathname):
check_files([pathname])
elif os.path.isdir(pathname):
for dirpath, dirnames, filenames in os.walk(pathname):
check_files(os.path.join(dirpath, f) for f in filenames)
else:
print "ERROR: '{0}' is neither a file or a dir.".format(pathname)
if __name__ == "__main__":
main()