使用CRC32还可实现图片去重功能,如下FindRepeatFile函数,运行后通过对所有文件做crc校验并将校验值存储至CatalogueDict字典内,接着依次提取CRC特征值并将其存储至CatalogueList列表内,接着通过统计特征值出现次数并将该次数放入到CountDict字典内,最后循环这个字典,并以此输出文件特征与重复次数,将重复值放入到RepeatFileFeatures列表内。

如下代码所示;

import zlib,os

def Find_Repeat_File(file_path,file_type):
Catalogue = os.listdir(file_path)
CatalogueDict = {} # 查询字典,方便后期查询键值对对应参数
for each in Catalogue:
path = (file_path + each)
if os.path.splitext(path)[1] == file_type:
with open(path,"rb") as fp:
crc32 = zlib.crc32(fp.read())
# print("[*] 文件名: {} CRC32校验: {}".format(path,str(crc32)))
CatalogueDict[each] = str(crc32)
CatalogueList = []
for value in CatalogueDict.values():
# 该过程实现提取字典中的crc32特征组合成列表 CatalogueList
CatalogueList.append(value) CountDict = {}
for each in CatalogueList:
# 该过程用于存储文件特征与特征重复次数,放入 CountDict
CountDict[each] = CatalogueList.count(each) RepeatFileFeatures = []
for key,value in CountDict.items():
# 循环查找字典中的数据,如果value大于1就存入 RepeatFileFeatures
if value > 1:
print("[-] 文件特征: {} 重复次数: {}".format(key,value))
RepeatFileFeatures.append(key) if __name__ == "__main__":
Find_Repeat_File("D://lyshark/",".png")

运行上述代码,则会扫描d://lyshark/目录下所有的png格式文件,并输出这些文件特征值,以及该特征的重复次数,如下图所示;

有了上述方法我们就可以实现去重了,当然上述方法还可以优化,通过使用groupby功能可以自动实现分组,f恩组后我们只需要对分组进行排序,并寻找对应符合条件的特征,找到后直接调用os.remove将其移除即可,实现代码如下所示;

import zlib,os,argparse
from operator import itemgetter
from itertools import groupby def Find_Repeat_File(file_path,file_type):
Catalogue = os.listdir(file_path)
CatalogueList = []
for each in Catalogue:
path = (file_path + each)
if os.path.splitext(path)[1] == file_type:
with open(path,"rb") as fp:
crc32 = zlib.crc32(fp.read())
# print("[*] 文件名: {} CRC32校验: {}".format(path,str(crc32)))
CatalogueList.append({ "CRC32": str(crc32) , "FILE": path }) # 首先排序,然后根据字典中的CRC32排序
CatalogueList.sort(key=itemgetter("CRC32"))
for key,value in groupby(CatalogueList,key=itemgetter("CRC32")):
# print("[*] CRC32特征码: {}\t".format(key))
for each in value:
RepeatNumber = len(list(value))
if (RepeatNumber+1) > 1:
try:
print("---> 重复图片: {} 已移除".format(each.values()))
os.remove(str(list(each.values())[1]))
except FileNotFoundError:
pass if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-d","--dirs",dest="dirs",help="指定目录路径")
parser.add_argument("-t","--types",dest="types",help="指定文件类型")
args = parser.parse_args()
# 使用方式: main.py -d "d://lyshark/" -t ".png"
if args.dirs and args.types:
os.chdir(args.dirs)
try:
for each in range(0,len(os.listdir())):
Find_Repeat_File("./",args.types)
except:
pass
else:
parser.print_help()

如下图所示,我们通过传入d://lyshark/并设置.png类型,扫描该目录下所有重复文件,并将该文件移除,输出效果如下图所示;

当然上述方法是一次性清楚重复文件,在某些时候我们希望存入文件后自动清理,此时就需要动态监控文件或目录变化,函数MonitoringDirectory()可用于动态监控用户目录,当有新文件创建时自动校验是否存在该文件如果存在则删除重复的,其实现原理是不间断的遍历目录,当有新文件产生时自动将该文件计算特征对比,如果重复则删除,该方式虽然可实现目录监控但效率却很低,因为要不间断的遍历目录。

import os, time
from zlib import crc32 # 计算目标CRC32
def Calculation_crc32(filename):
try:
with open(filename,"rb") as fp:
crc = crc32(fp.read())
while True:
temp = fp.read(8196)
if not temp:
break
fp.close()
return crc
except Exception:
fp.close()
return 0
return 0 # 开始监控目录
def MonitoringDirectory(path_to_watch):
crc_poll = [] before = dict([(f, None) for f in os.listdir(path_to_watch)])
while True:
time.sleep (0.3) after = dict ([(f, None) for f in os.listdir (path_to_watch)])
added = [f for f in after if not f in before]
removed = [f for f in before if not f in after] # 新增文件时触发
if added:
# print("新建文件: {}".format(added))
for index in range(0,len(added)):
# 计算文件CRC32
AbsolutePath = path_to_watch + "/" + added[index]
crc = Calculation_crc32(AbsolutePath)
print(f"计算文件路径: {AbsolutePath} 文件CRC32: {crc}") # 只要有新文件则加入到crc_pool
if crc != 0:
crc_poll.append(crc) print("池内数据: {}".format(crc_poll))
crc_count = 0 # 循环池内的所有CRC数据
for index in range(0,len(crc_poll)): # 如果当前文件CRC与池内某个一致则递增
if crc_poll[index] == crc:
crc_count = crc_count + 1 # 只要大于2则说明有重复的
if crc_count >= 2:
try:
print("存在校验值,删除文件: {}".format(AbsolutePath))
os.remove(AbsolutePath)
crc_poll.remove(crc)
except Exception:
pass
# 删除文件时触发
if removed:
print("移除文件: {}".format(removed))
before = after if __name__ == "__main__":
MonitoringDirectory("d://lyshark")

运行上述程序,则会监控d://lyshark目录,当有心文件被创建时会自动对比特征值,如果相同则会被清理,如果无重复的则会被保留,如下图所示;

21.11 Python 使用CRC图片去重的更多相关文章

  1. python爬取妹子图全站全部图片-可自行添加-线程-进程爬取,图片去重

    from bs4 import BeautifulSoupimport sys,os,requests,pymongo,timefrom lxml import etreedef get_fenlei ...

  2. 2016年12月16日 星期五 --出埃及记 Exodus 21:11

    2016年12月16日 星期五 --出埃及记 Exodus 21:11 If he does not provide her with these three things, she is to go ...

  3. python 将png图片格式转换生成gif动画

    先看知乎上面的一个连接 用Python写过哪些[脑洞大开]的小工具? https://www.zhihu.com/question/33646570/answer/157806339 这个哥们通过爬气 ...

  4. Python人工智能之图片识别,Python3一行代码实现图片文字识别

    1.Python人工智能之图片识别,Python3一行代码实现图片文字识别 2.tesseract-ocr安装包和中文语言包 注意:

  5. python使用set来去重碰到TypeError: unhashable type

    新版:Python 的 unhashable type 错误分析及解决 python使用set来去重是一种常用的方法. 一般使用方法如下: # int a = [1, 2, 3, 4, 5, 1, 2 ...

  6. PostgreSQL视频去重 图片去重系列1

    PostgreSQL 在视频.图片去重,图像搜索业务中的应用 图片搜索 PostgreSQL的图像搜索插件使用了非常主流的Haar wavelet技术对图像进行变换后存储 gist 索引方法(支持pa ...

  7. Python批量修改图片格式和尺寸

    Python批量修改图片格式和尺寸 备注: 1.导入了PIL库,是处理图片用的,很强大; 2.导入了的win32库,是判断隐藏文件用的,我们的项目需要删除隐藏文件,不需要的可以直接找到删除. 3.导入 ...

  8. 21行python代码实现拼写检查器

    引入 大家在使用谷歌或者百度搜索时,输入搜索内容时,谷歌总是能提供很好的拼写检查,比方你输入 speling,谷歌会立即返回 spelling. 前几天,看到http://norvig.com/spe ...

  9. Python 实现简单图片验证码登录

    朋友说公司要在测试环境做接口测试,登录时需要传入正确的图片的验证码,本着懒省事的原则,推荐他把测试环境的图片验证码写死,我们公司也是这么做的^_^.劝说无果/(ㄒoㄒ)/~~,只能通过 OCR 技术来 ...

  10. PostgreSQL 在视频、图片去重,图像搜索业务中的应用

    摘要: PostgreSQL 在视频.图片去重,图像搜索业务中的应用作者digoal日期2016-11-26标签PostgreSQL , Haar wavelet , 图像搜索 , 图片去重 , 视频 ...

随机推荐

  1. stm32f103 rt-thread fal easyflash移植过程

    需求:使用Stm32F103片内Flash进行数据存储 硬件平台:Stm32F103C8t6(由于Stm32F103C8t6的Flash标注为64k实际为128K,64KFlash在使用rt-thre ...

  2. 【有奖体验】AI 都这么厉害了,可以看图生成文字描述!

    立即体验基于函数计算部署[图生文]一键部署图像描述模型: https://developer.aliyun.com/topic/aigc_fc 人工智能生成内容(Artificial Intellig ...

  3. 【真送礼物】1 分钟 Serverless 极速部署盲盒平台,自己部署自己抽!

    当前,Serverless 在移动应用.游戏等场景已经实现规模化应用,Serverless 技术可以更好的帮助开发者只关注应用创新,减少对开发与运维的过度关注. 为了让更多开发者在真实场景中体验 Se ...

  4. 7、SpringBoot-mybatis-plus引入

    系列导航 springBoot项目打jar包 1.springboot工程新建(单模块) 2.springboot创建多模块工程 3.springboot连接数据库 4.SpringBoot连接数据库 ...

  5. [QML]从零开始QML开发(二)QML开发,浅谈控件、槽函数、锚等基本概念。QML和C++怎么交互?贯彻落实MVC原则

    [QML]从零开始QML开发(二)QML开发,浅谈控件.槽函数.锚等基本概念.QML和C++怎么交互?贯彻落实MVC原则 先看代码: import QtQuick 2.12 import QtQuic ...

  6. Spring boot 运行服务jar外配置配置文件方式总结

    本文为博主原创,转载请注明出处: 由于需要在本地编译打包,在服务器上验证某些功能,需要频繁修改配置,本地打包时,会将配置文件也打包的jar 包内部,这种方式下,若修改配置则需要本地修改重新上传服务器一 ...

  7. Linux复制安装 jdk 环境

    转载请注明出处: 最近在弄服务器环境,发现可以通过复制已安装 jdk 的服务器配置到新的服务器,并配置服务器环境变量配置文件就可以完成. 操作步骤如下: 1. 查看以安装jdk服务器的环境配置,并复制 ...

  8. linux 命令使用总结:vim,nohup,find,df,du,sudo,netstat,ll,curl,lastlog

    1.Vim命令使用 vim 为编辑文本命令: vim 文件  回车即可查看文件 按 字母 i 键,即可进入 insert 编辑模式. 按 ESC 键即可退出编辑模式 输入冒号:wq 即可保存修改 输入 ...

  9. 揭秘 Docker 网络:手动实现 Docker 桥接网络

    本文将带领读者探索 Docker 桥接网络模型的内部机制,通过手动实现 veth pair.bridge.iptables 等关键技术,揭示网络背后的运作原理. 如果你对云原生技术充满好奇,想要深入了 ...

  10. [转帖]SQLServer的UTF8支持

    排序规则和 Unicode 支持 - SQL Server | Microsoft Learn UTF-8 支持 SQL Server 2019 (15.x) 完全支持广泛使用的 UTF-8 字符编码 ...