Python检测JPEG、PNG是否完整(2)

本文介绍了如何利用Python的PIL库来精确检测JPEG和PNG图片的完整性,通过读取图片的各个字段,而非仅仅依赖于结束符。这种方法能有效处理含有冗余字段的图片,避免误判。

《OpenCV系列教程》
《深度学习-如何提高数据集质量》

在之前的博文中写过检测JPEG、PNG图片是否完整,通过结束符的检测能很好的发现图片没有下载完成。如下图的情况。
在这里插入图片描述
这种方式过于简单粗暴,其实判断图片到底能不能用,最终的答案是图片中各个字段能不能成功读取。能全部读取的,就可以认为这个是一个好的图片。
再看两个有冗余字段的文件。

这两个图片的二进制显示,但在图片文件结束的时候,被加入了很多数据。这个时候使用简单的结束符号判断显然不是正确的方法。最好的方法就是读取图片的各个字段。但编写读取字段的代码类似于重复制造车轮,所以我选择了“PIL”,他能很好的解决这个问题,由于效率问题仅仅对没有结束字符的图片进行二次筛查。代码如下:

import os
import shutil
from PIL import Image

DirList = [
    '/home/king/PycharmProjects/nsfw_data_scrapper/raw_data/drawings',
    '/home/king/PycharmProjects/nsfw_data_scrapper/raw_data/hentai',
    '/home/king/PycharmProjects/nsfw_data_scrapper/raw_data/neutral',
    '/home/king/PycharmProjects/nsfw_data_scrapper/raw_data/porn',
     '/home/king/PycharmProjects/nsfw_data_scrapper/raw_data/sexy'
]


def is_valid_jpg(jpg_file):
    with open(jpg_file, 'rb') as f:
        f.seek(-2, 2)
        buf = f.read()
        return buf == b'\xff\xd9'


def is_valid_png(png_file):
    with open(png_file, 'rb') as f:
        f.seek(-3, 2)
        buf = f.read()
        if buf == b'\x60\x82\x00':
            return True
        elif buf[1:] == b'\x60\x82':
            return True
        else:
            return False


def is_valid_pic(pic_file):
    if pic_file.endswith('jpeg'):
        return is_valid_jpg(pic_file)

    elif pic_file.endswith('png'):
        return is_valid_png(pic_file)
    else:
        return False


for path in DirList:
    for file in os.listdir(path):
        pic_file = os.path.join(path, file)
        if not is_valid_pic(pic_file):
            try:
                img = Image.open(pic_file)
                img.load()
            except Exception as e:
                #print(e)
                print(pic_file)
                #shutil.copy(pic_file, '/home/king/Desktop/')
                #os.remove(pic_file)

最后不完整的图片被打印出来。
网上还有一种方式是 Image.open(file).verify(),但通过这个检测,我发现我有大量大量的图片是不完整的,真的吓到我了。不知道是不是我的版本问题,最后被弃用了。

评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值