吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6752|回复: 36
收起左侧

[Python 原创] 【原创源码】删除重复图片

  [复制链接]
chenye1314 发表于 2020-9-27 16:55
本帖最后由 chenye1314 于 2020-10-28 20:00 编辑

今天闲来无事整理素材,发现有许多重复的图片,由于数量太多无法手动翻阅删除,想想写个代码,分析了一下重复图片有些是同名的,有些内容重复不同名,返回文件名清理放弃,图片大小也放弃放弃,后来选用计算MD5的方式清除,然后先是使用os.listdir()函数遍历文件夹下的图片,在测试过程中,如果文件夹下还包含文件夹就会引发异常,后来决定用os.walk()函数来遍历;

源码注释写的比较清晰,就不多阐述,可根据自己需要封装函数,制作成死循环,添加退出条件,复用;
部分源码展示
[Python] 纯文本查看 复制代码
try:
    file = os.walk(path)    # 递归遍历目录;
except FileNotFoundError:   # 捕获路径不存在异常;
    print('抱歉,没有这个路径!')
else:
    temp = set()    # 创建临时集合;
    del_count = 0   # 删除图片计数;
    pass_count = 0  # 非图片计数;
    file_count = 0  # 总文件计数;
    time1 = time()
    for path_name, dir_name, file_name in file:     # 遍历walk返回3个元素;
        for n in file_name:                         # 获得每个文件名字;
            full_path = os.path.join(path_name, n)  # 拼接路径和文件名,获得文件完整路径;
            file_count += 1                         # 文件计数+1;
            print(full_path)
            try:
                with Image.open(full_path) as t:    # 打开图片;
                    array = np.array(t)             # 转为数组;
            except (UnidentifiedImageError,DecompressionBombError): # 捕获不是图片,像素炸弹异常;
                pass_count += 1                                     # 非图片计数+1;
                pass
            else:
                md5 = hashlib.md5()                                 # 创建MD5对象;
                md5.update(array)                                   # 获取当前图片MD5;
                if md5.hexdigest() not in temp:                     # 如果哈希值没有在集合中;
                    temp.add(md5.hexdigest())                       # 就把哈希值添加到集合中;
                else:
                    os.remove(full_path)                            # 如果在集合中就删除当前图片;
                    print(full_path+'------------------已删除')
                    del_count += 1                                  # 删除计数+1

编译好的可执行EXE文件
链接:https://pan.baidu.com/s/18-ekvN40GT4Ezek29oaHXA
提取码:77vf

未清理前

未清理前
微信截图_20200927162637.png
微信截图_20200927163505.png

清理后

清理后

源码文件.zip

1.62 KB, 下载次数: 101, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 8吾爱币 +6 热心值 +7 收起 理由
zxlzry + 1 + 1 谢谢@Thanks!
gi204657 + 1 谢谢@Thanks!
a337100 + 1 + 1 谢谢@Thanks!
一花依世界 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
凯豫5V + 1 + 1 谢谢@Thanks!
crosskys + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Bizhi-1024 + 1 谢谢@Thanks!
然悟星陨 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

leonca 发表于 2020-9-27 21:51
本帖最后由 leonca 于 2020-9-27 21:52 编辑

批处理版本,计算文件的MD5值,并根据重复的MD5值筛选出重复的文件。不仅可用于图片,还可以用于其他文件。MD5的值只会根据文件内容而有所不同,跟文件名不同,所以你的文件内容有任何的变动都会导致MD5不同
例如,两张一模一样的照片经过了非常简单的PS,那也是不同的MD5值。所以这个批处理可以筛选出,完全一模一样的文件,但是不能完全筛选出相似的图片。
md5.zip (72.17 KB, 下载次数: 55)
这个附件是MD5的计算工具,随便解压放在一个地方。为了方便,我们需要设置这个文件的环境变量。
[Asm] 纯文本查看 复制代码
setx path "%path%;d:\md5" /m

上面的代码是设置环境变量的,其中D:\MD5代表的是解压出来的md5.exe放在D盘的md5文件夹下,如果你放的文件夹不同,那么修改一下就可以了。
下面是完整的批处理代码
将待检测的文件夹(例如文件夹是photo)直接拖到批处理上,批处理会自动运行,同时批处理所在目录会生成ret_list.txt、del_list.bat、photo_md5.txt三个文件。

①ret_list.txt中会写明是哪些文件重复了

②photo_md5.txt是该文件夹下包含子文件夹下的所有文件的md5值

③del_list.bat是自动生成的批处理删除重复文件,只需要双击即可删除重复文件,不过最好先打开看一下里面的内容。
[Asm] 纯文本查看 复制代码
@goto start
:help
@echo.===== Ver: 1.1 =========================== 发布日期: 2010-09-24 =======
@echo.        BAT_NAME:        findDupFile.bat
@echo.        返回值:                %ret_filename%
@echo.        作用  :                根据MD5值查找重复文件
@echo.        调用:        ①findDupFile.bat [Path [EXT]] [file]
@echo.                ②findDupFile.bat [Path [EXT]] [file] [MD5_file1]
@echo.                ③findDupFile.bat [MD5_file1] [MD5_file2]
@echo.                [Path]:        文件夹路径 (可以是多个)
@echo.                [file]:        文件 (可以是多个)
@echo.                [EXT] :        文件后缀 如:"*.jpg *.bmp",带空格的必须用引号括起来
@echo.                [MD5_file] :        MD5文件,形如"*_MD5.txt",带空格的必须用引号括起来
@echo.====================== Copyright[url=home.php?mod=space&uid=402414]@[/url] by hf-g ========= [彭城] ============
ping /n 4 127.1>nul
goto:end
:start ============================================================
@echo off&setlocal
path=%path%;%~d0\DOS\command\第三方命令行程序
set "ret_filename=%~dp0.\ret_List.txt"
if /i "%~1"=="" goto help
if /i "%~1"=="-?" goto help
set "ext="&set "pathname="&set "Dir_name="&set "MD5_file1="&set "MD5_file2="&set "p_str="
set /a exit_BL=0,D_count=0,f_count=0

call:get_P %*
if "%exit_BL%"=="1" goto end
::设置临时文件
set "tmpfname=%pathname_0:~-2%"
if "%tmpfname%"==":\" (
set "Dir_name=drive_%pathname_0:~0,1%"
call echo 驱动器名:        %%Dir_name%%
) else (
        if "%pathname_0:~-1%"=="\" (
        call call:extpath "%%pathname_0:~0,-1%%"
        call echo 文件夹名:        %%Dir_name%%
        ) else (
                if exist "%~1\" (
                set "Dir_name=%~nx1"
                call echo 文件夹名:        %%Dir_name%%
                )
        )
)
if %f_count% GTR 0 set "Dir_name=list"
if %D_count% GTR 1 set "Dir_name=list"

set "tmpfname=%~dp0.\%Dir_name%_MD5.txt"
cd.>"%ret_filename%"
echo 生成MD5文件:            %tmpfname%
echo 相同文件列表:           %ret_filename%
echo 删除重复文件BAT:        del_list.bat
::========================MAIN============================
::生成MD5文件,可一次处理多个文件夹和文件,只在批处理所在文件夹生成1个MD5文件.
::set "ext=*.jpg *.bmp"
set/a D_count-=1,f_count-=1
if not "%pathname_0%"=="" (
cd.>"%tmpfname%"
for /l %%i in (0,1,%D_count%) do (
call pushd "%%pathname_%%i%%"
(for /f "tokens=* delims=" %%i in ('dir /a-d/b/s %ext%') do (md5 "%%i"))>>"%tmpfname%"
popd
))
if not "%file_0%"=="" (
if "%pathname_0%"=="" cd.>"%tmpfname%"
for /l %%i in (0,1,%f_count%) do (call md5 "%%file_%%i%%")>>"%tmpfname%"
)
::处理MD5文件━━━━━━━━━━━━━━━━━━━━━━━━━━━━
cd.>"%~dp0.\del_list.bat"
if "%MD5_file1%"=="" (
rem =========查找上面"生成MD5文件"中相同的文件,删除重复的====
call:MD5_1file "%tmpfname%"
) else (
        if "%MD5_file2%"=="" (
                if not exist "%tmpfname%" (
                        rem =========查找原有的唯一MD5列表文件中相同的文件,删除重复的====
                        call:MD5_1file "%MD5_file1%"
                ) else (
                        rem =========查找上面"生成MD5文件"与原有MD5文件中相同的文件,删除重复的====
                        call:MD5_2file "%MD5_file1%" "%tmpfname%"
                )
        ) else (
                rem =========查找原有MD5_file1与原有MD5_file2文件中相同的文件,删除重复的====
                call:MD5_2file "%MD5_file1%" "%MD5_file2%"
        )
)

:end ==============================================================
::if exist "%tmpfname%" del "%tmpfname%" "%~dp0.\del_list.bat"
exit /b
::=========查找MD5列表文件中相同的文件,删除重复的====
:MD5_1file MD5_file
for /f "tokens=1* delims= " %%a in ('type "%~1"') do (
        set/p =-<nul
        if defined _MD5_%%a (
                set/p =\<nul
                echo [url=home.php?mod=space&uid=324026]@Del[/url] /f/q "%%b">>"%~dp0.\del_list.bat"
                set/p =^|<nul
                if not defined _write_%%a (findstr "^%%a" "%~1">>"%ret_filename%"&echo.>>"%ret_filename%"&set "_write_%%a=1")
        ) else (
                set "_MD5_%%a=1"
        )
        set/p =/<nul
)
goto:eof
::=========查找MD5_file1中与MD5_file2相同的文件,删除MD5_file2中重复的====
:MD5_2file MD5_file1 MD5_file2
(echo MD5_file1=%~1&echo MD5_file2=%~2)>con
(echo MD5_file1=%~1&echo MD5_file2=%~2&echo.)>>"%ret_filename%"
for /f "tokens=1* delims= " %%a in ('type "%~1"') do (set "_MD5_%%a=%%b")
for /f "tokens=1* delims= " %%a in ('type "%~2"') do (
        set/p =-<nul
        if defined _MD5_%%a (
                set/p =\<nul
                echo @del /f/q "%%b">>"%~dp0.\del_list.bat"
                set/p =^|<nul
                (set _MD5_%%a&echo      %%a %%b&echo.)>>"%ret_filename%"
                set/p =/<nul
        )
)
goto:eof
::====================================================
:extpath
set "Dir_name=%~nx1"
goto:eof
::========================参数设置与获得============================
:get_p
::判断%1是_MD5.txt还是文件夹或其他文件或文件后缀
if "%~1"=="" goto:eof
set "p_str=%~1"
if exist "%p_str%" (
        if "%p_str:~-8%"=="_MD5.txt" (
                if "%MD5_file1%"=="" (
                set "MD5_file1=%p_str%"&shift /1&goto get_p
                ) else (
                        set "MD5_file2=%p_str%"&shift /1&goto get_p
                )
        )
        if exist "%p_str%.\" (
        call set "pathname_%%D_count%%=%p_str%"&set /a D_count+=1&shift /1&goto get_p
        )
        call set "file_%%f_count%%=%p_str%"&set /a f_count+=1&shift /1&goto get_p
) else (
        if "%ext%"=="" (
                if "%p_str:~0,2%"=="*." (
                set "ext=%p_str%"&shift /1&goto get_p
                )
        )
        echo %p_str% 不是一个正确的文件夹路径或文件^!&set /a exit_BL=1&shift /1&goto end
)
@echo off
:get_p_end
goto:eof

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
chenye1314 + 1 + 1 我很赞同!

查看全部评分

沉鱼雁 发表于 2020-9-27 17:25
本帖最后由 沉鱼雁 于 2020-10-8 13:21 编辑

已搬运,免登录不限速
https://ws28.cn/f/3lpjmsgtbt8

hw520wh 发表于 2020-9-27 16:58
 楼主| chenye1314 发表于 2020-9-27 17:00
hw520wh 发表于 2020-9-27 16:58
问问这删的是名字重复还是内容重复

内容重复的
hw520wh 发表于 2020-9-27 17:02

那给力呀
win6 发表于 2020-9-27 17:05
感谢分享,这个很有用
青词倾慕 发表于 2020-9-27 17:11
可以筛选类似图片吗?
电竞彭于晏 发表于 2020-9-27 17:23
感谢分享
流星之忆 发表于 2020-9-27 17:24

感谢分享
凯豫5V 发表于 2020-9-27 18:05
这个很给力了,多谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 17:29

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表