ทำการสแกนไฟล์กราฟิกโดยอัตโนมัติเพื่อให้เกิดความเสียหาย


27

ไม่มีใครรู้วิธีตรวจสอบไฟล์กราฟิก (โดยเฉพาะ JPEG, GIF และ PNG) สำหรับความเสียหาย (โดยเฉพาะอย่างยิ่งในวิธีอัตโนมัติ)?


คำอธิบาย:

ไม่กี่วันที่ผ่านมาคำสั่งทำงานอย่างไม่ถูกต้องและสิ้นสุดการลบไฟล์กราฟิกนับพันจากวอลุ่ม FAT32 ที่ไม่ได้ใช้งานจริง ฉันใช้โปรแกรมกู้คืนไฟล์ / ภาพถ่ายที่แตกต่างกันหลายตัว แต่โดยธรรมชาติพวกมันมีข้อ จำกัด ในการกู้คืน (แต่โชคดีที่ไดรฟ์ข้อมูลมีคลัสเตอร์ 8KB ซึ่งช่วยได้บ้าง)

อย่างไรก็ตามไฟล์ที่มีขนาดใหญ่กว่าบางไฟล์ซึ่งมีการแยกส่วนนั้นเสียหายแล้ว บางไฟล์ไม่ได้เป็นไฟล์จริงเลย (ซอฟต์แวร์กู้คืนจะทิ้งเฉพาะกลุ่มที่ชี้ไปยังรายการไดเรกทอรีที่เขียนทับตอนนี้) ในขณะที่คนอื่นเสียเนื่องจากการแตกแฟรกเมนต์

ยิ่งกว่านั้นเนื่องจากรูปแบบรูปภาพบางรูปแบบฝังรูปภาพขนาดเล็กลงเป็นรูปขนาดย่อการสแกนรูปขนาดย่อเพื่อการคอร์รัปชั่นไม่น่าเชื่อถือเนื่องจากอาจไม่เป็นอันตรายในขณะที่ไฟล์จริง (เช่นรูปภาพเมื่อดูขนาดเต็ม) อาจเสียหาย


นี่คือตัวอย่างบางส่วน:

นี่คืออันที่สอง มันเสียหายมากจนไม่แสดงอะไรเลย

ภาพที่เสียหาย

(อันที่สามจะไม่อัปโหลดเพราะมันไม่มีส่วนหัวที่ถูกต้อง!)


คุณหมายถึงความเสียหายทางสายตาฉันคิดว่า? ฉันจะรักสิ่งนี้ ... ในที่สุดฉันก็สามารถหยุดการดูภาพขนาดย่อของหนังสือการ์ตูนของฉันสำหรับ jpgs ที่เสียหายได้
Shinrai

ภาพหรือโครงสร้าง ฉันพบแอปหนึ่งที่ควรทำสิ่งนี้ แต่มันพลาดไฟล์จำนวนมากที่ไม่มีส่วนหัว !
Synetech

โอ้สิ่งนั้นไม่ได้เกิดขึ้นกับฉัน ใช่โปรด ... สิ่งนี้ต้องมีอยู่ไม่นานใช่ไหม
Shinrai

1
คุณสามารถอัปโหลดตัวอย่างหนึ่งไฟล์หรือมากกว่าของไฟล์ที่เสียหายและเชื่อมโยงไปยังพวกเขาในคำถามของคุณ?
slhck

@Shinrai การตรวจสอบรูปขนาดย่อนั้นไม่น่าเชื่อถือเนื่องจากรูปแบบภาพจำนวนมากมีรูปแบบย่อขนาดแยกต่างหากซึ่งฝังอยู่ในภาพและอาจไม่เป็นอันตราย นั่นเป็นสาเหตุที่บางครั้งรูปภาพที่มีภาพขนาดเล็กดูดีเสียหายเมื่อเปิด
Synetech

คำตอบ:


12

เนื่องจากฉันพบสิ่งนี้ในขณะที่พยายามตอบคำถามเดียวกันฉันจะเพิ่มโซลูชันที่ยอดเยี่ยมอีกอันที่ฉันพบ:

เพ็กกี้ไม่ดี

สกรีนช็อตของแอปพลิเคชัน

การใช้งาน
จากเมนูให้เลือกFile > Scanจากนั้นใช้กล่องโต้ตอบไฟล์เพื่อเรียกดูไปยังโฟลเดอร์ที่มีภาพอยู่ โปรแกรมจะเริ่มสแกนโฟลเดอร์และโฟลเดอร์ย่อยทั้งหมดเพื่อค้นหารูปภาพ (.jpg, .png, .bmp, .gif) หากคุณต้องการสแกนภาพจำนวนมากอาจต้องใช้เวลาสักครู่เนื่องจากโปรแกรมต้องการโหลดและแยกไฟล์รูปภาพอย่างสมบูรณ์ดังนั้นคุณอาจต้องการให้มันทำงานข้ามคืน

ในขณะที่กำลังสแกนมันจะแสดงเปอร์เซ็นต์ความคืบหน้าในแถบสถานะ ภาพใด ๆ ที่พบว่าไม่สมบูรณ์จะปรากฏขึ้นโดยตรงในรายการ หากคุณคลิกที่ภาพใด ๆ ในรายการมันจะแสดงตัวอย่างของภาพที่มีลักษณะ บ่อยครั้งที่ภาพจะมีปัญหาเล็กน้อยกับรูปแบบไฟล์และภาพจะยังดูดี ในบางครั้งภาพจะไม่แสดงผลเลยและภาพตัวอย่างจะเป็นสีดำ บางครั้งภาพอาจเสียหายและคุณจะเห็นบางอย่างคล้ายกับภาพหน้าจอด้านบน

เคล็ดลับที่มีประโยชน์มากคือการคลิกที่ส่วนหัวของคอลัมน์Reasonและรูปภาพจะถูกจัดเรียงตามความเสียหายที่ไม่ดี (เช่นรูปแบบไฟล์ที่ไม่ดีทั้งหมดที่ยังคงแสดงผลอย่างถูกต้องจะย้ายไปที่ด้านล่างเพื่อให้คุณมุ่งเน้นไปที่ .

นอกจากนี้หากการสแกนครั้งแรกเสร็จสิ้นและคุณเริ่มการสแกนอีกครั้งผลลัพธ์จะถูกเพิ่มลงในรายการ ดังนั้นหากคุณมีโฟลเดอร์ต่าง ๆ มากมายที่มีรูปภาพคุณสามารถสแกนมันตามลำดับโดยไม่ต้องลบรายการเมื่อคุณเริ่มการสแกนใหม่ Clear listหากคุณไม่ต้องการรายชื่อเพื่อล้างใช้เมนูบริบทและคลิก

ลิงค์
ดาวน์โหลดสำหรับ Windows, Linux และ OS X มีอยู่ที่นี่:
https://www.coderslagoon.com

ซอร์สโค้ดอยู่ที่นี่:
https://github.com/llaith/BadPeggy


ขอบคุณสำหรับการแก้ไข ฉันได้เพิ่มข้อมูลการใช้งานเล็กน้อย (แม้ว่าโปรแกรมจะอธิบายตนเองได้ดี)
พอล

ลิงก์ซอร์สโค้ดเสียหาย
Nicolas Raoul

9

ลองใช้ตัวเลือกjpeginfo ' -c' สำหรับไฟล์ JPEG ของคุณ

ฉันเคยเห็นความเสียหายที่คุณแสดงเกิดขึ้นกับการ์ดหน่วยความจำที่ไม่ดีเช่นกัน
สิ่งที่คุณต้องการจะเป็นไปได้และพร้อมให้ตรวจสอบความเสียหายของไฟล์กราฟิก ;
ส่วนจากออนไลน์สารานุกรมของกราฟิกรูปแบบไฟล์

ยังเห็นไฟล์ตรวจสอบความสมบูรณ์ในบทนำพื้นฐานเพื่อPNGคุณสมบัติ

คุณอาจสนใจคำถาม Stackoverflow นี้
ฉันจะตรวจสอบโดยทางโปรแกรมได้อย่างไรว่าภาพ (PNG, JPEG หรือ GIF) เสียหายหรือไม่


ปรับปรุง : มา tarballสำหรับเวอร์ชัน 1.6.1โดยTimo Kokkonen
คุณควรสร้างไบนารี่สำหรับเครื่องของคุณ


ขออภัยฉันไม่พบพอร์ต Windows ใด ๆ
Synetech

jpeginfo เป็นโอเพ่นซอร์ส; คุณควรจะสามารถรับ tarball และรวบรวมมันในระบบของคุณ (อาจเป็นกับ Cygwin ที่มี libjpeg)
nik

มันเป็นสิ่งที่ moot อย่างใดอย่างหนึ่งเพราะฉันต้องสแกนอย่างน้อย GIF และ PNG เช่นกัน
Synetech

1
@nik - ไดเรกทอรี aux ซึ่งเป็นส่วนหนึ่งของ tarball ของ jpeginfo ไม่สามารถสร้างได้ภายใต้ชื่อบน Windows ทำให้ยากมากที่จะแยกไฟล์ภายใต้ Windows สร้างได้เพียงลำพัง คุณสามารถสร้างมันภายใต้ Windows ได้หรือไม่?
โกง

jpeginfo -c *.JPG | ag (WARNING|ERROR)ทำงานให้ฉัน
Selrond

3

โปรแกรมระบุตัวตนของ ImageMagickจะแจ้งให้คุณทราบหากภาพเสียหาย A 'for i in find' การทดสอบลูปสำหรับโค้ดส่งคืน none-0 จากการระบุจะช่วยให้คุณสคริปต์ทดสอบได้อย่างง่ายดายเพื่อดัมพ์รายการไฟล์ที่เสียหายหรือเสียหาย มันทำงานบน Windows ด้วย PowerShell ด้วย

ป้อนคำอธิบายรูปภาพที่นี่

รหัสต่อไปนี้พร้อมการเปลี่ยนแปลงสำหรับเส้นทางของคุณทำงานได้ดีใน 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()

ฉันไม่ได้ใช้ ImageMagick ในช่วงเวลาหนึ่ง (มันมีข้อผิดพลาดในครั้งล่าสุดที่ฉันพยายาม) แต่ฉันจะตรวจสอบมัน ขอบคุณสำหรับคำแนะนำ
Synetech

1
เครื่องมือของผู้ดูยังคงเป็นบั๊กกี้ แต่การระบุว่าทำงานได้ดีสำหรับฉันด้วยปัญหาที่คล้ายกัน ฉันใช้สคริปต์ PowerShell เช่นนี้เพื่อรับรายการไฟล์ภาพที่เสียหายและหรือ 0
OldWolf

@Synetech inc. ขออภัยไม่สามารถอัปเดตโพสต์ต้นฉบับด้วยรหัสที่จัดรูปแบบเนื่องจากมีการโพสต์ภาพและฉันไม่สามารถทำให้รูปแบบนี้เป็นรูปแบบได้ ตัวอย่างสคริปต์ Powershell: (ปรับเส้นทางประเภทไฟล์ของคุณ ฯลฯ ) $ stream = [System.IO.StreamWriter] "เสียหาย _jpegs.txt" get-childitem "c: \" -include * .jpg -recurse | foreach ($ _) {& "C: \ Program Files \ ImageMagick-6.7.1-Q16 \ ident.exe" $ _. fullname> $ null ถ้า ($ LastExitCode -ne 0) {$ stream.writeline ($ _ fullname)}} $ stream.close ()
OldWolf

1
จากบรรทัดคำสั่งidentifyสามารถแสดงข้อมูล JPEG ที่เสียหายด้วย-verboseโดยปกติจะไม่แสดง
kenorb

3

ซึ่งสามารถทำได้โดยใช้การถ่ายภาพห้องสมุดหลาม.verify()คำสั่ง [1]

ในการรันใน Windows ให้ติดตั้งPython (ฉันได้ติดตั้ง Python 2 รุ่นล่าสุดในปัจจุบัน) แล้วติดตั้งPillow (ทางแยกของ Python Imaging Library (PIL)) จากนั้นคัดลอกรหัสของjpeg_corrupt.py [2]และบันทึกเนื้อหาลงในไฟล์. PY เช่น jpeg_corrupt.py

โปรดทราบว่าฉันเปลี่ยนบรรทัดของรหัสต่อไปนี้ในjpeg_corrupt.py :
self.globs = ['*.jpg', '*.jpe', '*.jpeg']
เป็น
self.globs = ['*.jpg', '*.jpe', '*.jpeg', '*.png', '*.gif']
This ดังนั้นไฟล์. PNG และ. GIF ก็จะถูกสแกนด้วยเช่นกัน

จากนั้นจะสามารถดำเนินการผ่านทางพรอมต์คำสั่ง Windows (cmd.exe) ดังนี้: C:\Python27\python.exe "C:\Directory containing the .PY file\jpeg_corrupt.py" "C:\Directory of folder to be scanned"

ส่วนแรกของคำสั่ง ' C: \ Python27 \ python.exe ' อาจแตกต่างกันไปขึ้นอยู่กับเวอร์ชันของ Python ที่คุณติดตั้งและไดเรกทอรีที่คุณติดตั้ง ในตัวอย่างของฉันมันเป็นไดเรกทอรีการติดตั้งเริ่มต้นของ Python 2.7

ควรสแกนภาพ JPG, GIF และ PNG ทั้งหมดในไดเรกทอรีที่ระบุและไดเรกทอรีย่อยทั้งหมด มันจะแสดงผลลัพธ์หากตรวจพบไฟล์ภาพที่เสียหาย

ฉันวิ่งนี้ในภาพตัวอย่างของ OP ...\YcB9n.png: string index out of rangeและให้ข้อผิดพลาดนี้:

สามารถป้อนรหัสในไฟล์สคริปต์. BAT เพื่อให้คุณสามารถเรียกใช้ไดเรกทอรีที่ระบุโดยไม่จำเป็นต้องใช้พรอมต์คำสั่ง:

C:\Python27\python.exe "C:\Directory containing the .PY file\jpeg_corrupt.py" "%CD%"
pause



แหล่งที่มา:

[1]: คำตอบใน Stack Overflow - "ฉันจะตรวจสอบโดยทางโปรแกรมได้อย่างไรว่าภาพ (PNG, JPEG หรือ GIF) เสียหายหรือไม่" โดย ChristopheD
[2]: ความคิดเห็นโดย Denilson Sáในคำตอบ SO เชื่อมโยงใน [1]


4
ฉันลบบางส่วนของไฟล์ jpg แบบสุ่ม - สคริปต์ไม่แสดงอะไรเลย ตรวจพบข้อผิดพลาดในกรณีที่เลวร้ายที่สุดเท่านั้น - เมื่อส่วนหัวจะพลาดอย่างสมบูรณ์เช่น ...
พาเวล Vlasov

ตรงไปตรงมาสำหรับ jpeginfo
wp78de

2

ฉันได้แก้ไขโค้ดจากคำตอบของ galacticninjaเพื่อทำสิ่งที่ OP ต้องการ มันทำงานในลักษณะเดียวกันอย่างไรก็ตามมันจะย้ายไฟล์ไปยังโฟลเดอร์ catch ในC:\ไดเรกทอรีรากแทนที่จะเพียงแค่แสดงรูปภาพในพรอมต์คำสั่ง

คุณสามารถค้นหารหัสที่แก้ไขแล้วได้ที่ 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()

2

ติดตั้ง imagemagick หากคุณใช้ Mac คุณสามารถใช้ Homebrew

brew update && brew install imagemagick

จากนั้นคุณสามารถใช้สคริปต์ Python ขนาดเล็กนี้

import os
from subprocess import Popen, PIPE

def checkImage(fn):
    proc = Popen(['identify', '-verbose', fn], stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()
    exitcode = proc.returncode

    return exitcode, out, err

for directory, subdirectories, files in os.walk('/Your/Path/To/Files/'):
    for file in files:
        filePath = os.path.join(directory, file)
        code, output, error = checkImage(filePath)
        if code != 0 or error != '':
            print(str(code)+' '+error)
            #os.remove(filePath)

แทนที่/Your/Path/To/Files/และยกเลิกหมายเหตุบรรทัดสุดท้ายหากคุณต้องการลบภาพที่เสียหาย


1

ใช้identifyจากแพ็คเกจ ImageMagick

ตัวอย่างตัวอย่าง:

identify -verbose -regard-warnings my_file.jpg >/dev/null && echo File is OK. || echo File is corrupted.

และคำสั่งต่อไปนี้จะระบุไฟล์ JPEG ที่เสียหายทั้งหมดในโฟลเดอร์ปัจจุบัน:

find . -name \*.jpg -exec identify -verbose -regard-warnings {} >/dev/null "+"

0

หากคุณติดตั้ง Perl แล้วคุณสามารถใช้สคริปต์นี้ คุณต้องบันทึกรายการไฟล์เพื่อตรวจสอบใน f.txt ก่อนที่จะเรียกใช้สคริปต์ คุณสามารถสร้างรายการนี้โดยใช้ Irfanview (โหลดนิ้วหัวแม่มือทั้งหมดจากโฟลเดอร์ย่อยและบันทึกเป็น txt) รายการไฟล์ที่ดีจะถูกบันทึกใน okf.txt และไฟล์ที่เสียหายจะแสดงรายการใน brokenf.txt

=====================

use Image::Magick;

open(BROKEN, ">>brokenf.txt");  # Open for appending
open(OK, ">>okf.txt");  # Open for appending
$list='f.txt';          
open(TOSORT, $list) or die("Could not open  file."); 
foreach $pic (<TOSORT>)  {     
    chomp($pic);   
    $p = new Image::Magick;
    $s = 0;    
    $error = $p->Read($pic);
        if ($error) {print BROKEN $pic . "\n";
                   }     
           else {
                  print OK $pic . "\n"; 
                }  
    }
close(TOSORT);
close(BROKEN);
close(OK);
    }

close(TOSORT);
close(BROKEN);
close(OK);

0

My open source Pyhton script check-media-integrityตรวจสอบความสมบูรณ์ของรูปภาพและไฟล์วิดีโอ / เสียง มันใช้โมดูล Pillow, ImageMagick และ FFmpeg wrappers เพื่อลองถอดรหัสไฟล์

หมอน image.verify ไม่เห็นข้อบกพร่องทั้งหมด (เช่นละเว้นการถูกตัดทอน) ด้วยเหตุนี้ฉันยังทำการจัดการอิมเมจ / ถอดรหัส +


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.