使用Python进行图片去重处理

需求背景

最近给电脑换桌面背景的时候,想起硬盘里还有之前大学时期下载的搜狗壁纸图片,于是从硬盘将壁纸文件夹拷贝到电脑上,打开后发现有两个目录都保存有壁纸,每个都有几百张,但是有些是各自目录独有的,也有互相重复的。为了能够获得最完整的壁纸合集,打算将所有图片进行合并去重,很明显,这么重复枯燥的工作不可能人工去一张一张地比对处理(其实我一开始真的手动处理了几张,发现实在hold不住),作为一名程序猿,当然要使用随身佩带的武器(Programming)来披荆斩棘,虽然我是Java开发者,但是显然这种场景最适合出手的还是Python这把小巧轻灵的匕首。

多说一句,以前的搜狗壁纸真的是个很良心的壁纸软件,有很多精美的壁纸,还是免费的,后来好像因为不盈利而停止运行了,可惜之前没有多下载一些好看的壁纸。现在有时候找壁纸都是去国外的壁纸网站,没有之前直接在客户端下载那么方便了。

事先说明,我是一个Python菜鸟,学完Python基础后,如果长时间不用就要重新看教程的那种。

思路分析

  1. 首先遍历需要去重的图片集,计算图片的md5值(很多软件下载页面都会提供md5值用于检查数据完整性)
  2. 判断字典中是否存在该图片的md5值,如果不存在,将md5值作为key,图片文件作为value存入字典中
  3. 如果字典中存在md5值,表示存在重复的图片,将当前图片标记或直接删除
  4. 如果图片名称不规则,遍历图片集,一一重命名

开始上手

  1. 重复图片预览

  2. 主代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    # -*- coding: utf-8 -*-
    import hashlib
    import os


    # 获取图片md5值
    def get_md5(filename):
    file_txt = open(filename, 'rb').read()
    m = hashlib.md5(file_txt)
    return m.hexdigest()


    def main():
    path = 'D:\搜狗壁纸下载\python_test'
    md5_dict = {} # md5字典
    file_count = 0 # 总图片数
    real_count = 0 # 去重后图片数
    dup_count = 0 # 重复图片数
    for file in os.listdir(path):
    real_path = os.path.join(path, file)
    if os.path.isfile(real_path):
    file_md5 = get_md5(real_path)
    file_count += 1

    if md5_dict.get(file_md5):
    # 当前图片不在md5对应的图片列表中,说明该图片重复
    if not (file in md5_dict.get(file_md5)):
    print('发现相似图片------> ', '当前图片: ', file, '相似图片: ', md5_dict.get(file_md5))
    md5_dict.get(file_md5).append(file)
    dup_count += 1
    # os.remove(real_path) # 删除重复图片
    # print('删除图片: ', file)
    else:
    md5_dict[file_md5] = [file]

    print('========================================================================')
    print('========================================================================')
    print('========================================================================')

    real_count = len(md5_dict)
    print('总图片数: ', file_count, '| 重复图片数: ', dup_count, '| 去重后图片数: ', real_count)
    for key in md5_dict.keys():
    if len(md5_dict.get(key)) > 1:
    print('图片md5: ', key, '相似图片: ', md5_dict.get(key))
    else:
    print('图片: ', md5_dict.get(key), '无相似图片')


    def rename_wallpaper():
    path = 'D:\搜狗壁纸下载\python_test'
    file_name_prefix = '壁纸'
    count = 0
    for file_name in os.listdir(path):
    count += 1
    file_name_suffix = os.path.splitext(file_name)[-1]
    os.renames(os.path.join(path, file_name), os.path.join(path, file_name_prefix + str(count) + file_name_suffix))


    if __name__ == '__main__':
    main()
    # rename_wallpaper()
  3. 查看控制台输出(未实际删除)

  4. 查看删除后目录

这里只是提供了一种去除重复文件的简单思路,实际上有很多方法都可以实现这个功能,不过作为程序猿,这种折腾、自己造轮子的经历也是帮助我们提高自己的一种手段。