设计狮别用PS切图了!Python像素炼丹术炸平UI流水线——老板的旅游照被我哈希去重后自动生成视频素材(附源码|可白嫖)

「科班UI圈视我为邪教🔥,Adobe信徒骂我叛道离经🖌️——今天本怪蜀黎炮口抬高一寸,轰穿设计圈天花板!

老夫乃:🖼️设计界的符咒道士——不用PS,只写Python像素炼丹术🧪📸摄影界的码农哨兵——敢把《芥子园画谱》编译成OpenCV算法🌄🎬视频界的ERP土匪——抢素材如探囊取物,哈希去重如秋风扫落叶🍂

懵逼否?😵 愤怒否?💢

要的就是你们跪求Adobe订阅又舍不得删我脚本的样子!😎」

—————————————————-

🚀各位兄弟姐妹,缺素材的去”爱给网”我的主页下载,海量素材等你来薅:

💥开头:

「老板出差回来,丢过来一个文件夹说:‘这些风景照拍得不错,帮我整理成图册/视频素材!’ 📂
打开一看——好家伙!🌲同一棵树连拍10张、🌊同一个湖角度雷同、🏔️雪山重复到怀疑人生…
手动删到眼瞎还容易漏,怎么办?😫

今天分享一个Python自动化脚本,专治各种重复照片强迫症!

✅ 递归扫描9种格式图片(JPG/PNG/GIF/WEBP/EPS/PSD/AI…)

✅ 多线程计算哈希(MD5+文件大小混合指纹)⚡

✅ 3种删除策略(保留最新/最旧/手动选择)🛡️

✅ 生成可视化HTML报告,删除前后一目了然📊

亲测1000张照片去重只要3秒钟,老板看完直呼内行~👏」

—————————————————-

🚀过程:

1️⃣ 扫描阶段🔍 递归爬取文件夹,锁定9类图片格式(连设计师的PSD/AI稿都不放过!)📦 自动按文件大小分组——大小不同直接跳过,加速比对!

2️⃣ 哈希计算

⚡ 多线程并发计算(CPU核数×2,火力全开!)🧬 混合指纹:文件大小+MD5内容哈希,双重保险防误杀!

3️⃣ 去重策略

🕰️ 保留最旧:怀旧党必备(原始素材最珍贵)🔥 保留最新:更新党狂喜(留最新拍摄版本)✋ 手动选择:选择困难症福音(逐个确认再删)

4️⃣ 可视化报告

📝 自动生成HTML报告,带缩略图对比+文件信息(路径/大小/时间)🎯 删除前预览,避免误删老板心头好!

5️⃣ 一键执行

🐍 代码复制即用,路径/策略随心配置💾 释放磁盘空间,顺便拯救发际线!

—————————————————-

科班设计师怎么做?

❌用肉眼筛到瞳孔地震❌用PS批量调到手指抽筋❌用Final Cut渲染到天亮

本怪蜀黎野路子:

✅哈希去重——一招MD5+文件大小混合指纹,重复照片瞬间现形(今天更新)✅自动拆分归档——5000张图片随意按除以倍数分割到文件夹(下篇我会更新)✅视频素材预处理——批量调尺寸+加滤镜+转格式,直接喂给剪映PR

—————————————————-


# 伪代码预览(完整代码见下文)
1. 扫描所有图片 → 🗂️
2. 按大小分组 → 📊
3. 多线程哈希比对 → ⚡
4. 生成报告 → 📝
5. 执行删除 → 🗑️

🔔安全警告(醒目强调版):

⚠️ 操作前必读(防翻车指南):
1️⃣ 备份原文件:

📦 运行脚本前,务必先复制一份原始照片文件夹!💥 防止误删珍贵素材,数据无价,删错不赔!

2️⃣ 路径输入格式:

🗂️ 支持绝对路径(如C:Users老板旅游照)或相对路径(如./老板照片)🔍 示例:直接粘贴文件夹路径,不用加引号!

3️⃣ 模式选择提示:

🔄 脚本启动后会问删除策略:输入 keep_oldest → 保留最旧文件(默认)输入 keep_newest → 保留最新文件输入 manual → 手动选择保留(逐个确认)

4️⃣ 确认环节:

👀 生成HTML报告后会自动弹出预览!✅ 仔细核对重复组,确认无误再删!

🚀示例运行流程:


请输入要扫描的目录路径: D:老板的旅游照  
请选择删除策略(keep_oldest/keep_newest/manual): manual  

⚡ 开始扫描 D:老板的旅游照...  
🔍 找到 1588 个图片文件  
🎯 发现 42 组重复文件  
📊 可视化报告已生成:D:老板的旅游照重复文件报告.html  

是否查看报告后再删除?(y/n) y  
(报告自动打开,请核对缩略图!)  
确认执行删除操作?(y/n) y  
🗑️ 已删除:D:老板的旅游照雪山(1).jpg (4.2 MB)  
🗑️ 已删除:D:老板的旅游照湖面(2).png (3.8 MB)  
✅ 清理完成!共删除 86 个文件,释放 1.2 GB 空间  

import os
import hashlib
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
from collections import defaultdict
import time

# 配置区 可以新增格式 自己添加图片文件后缀
IMAGE_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.gif',
                    '.bmp', '.webp','.eps','.psd','.ai'}
THREADS = os.cpu_count() * 2
DELETE_STRATEGY = "keep_oldest"  # 可选: keep_oldest / keep_newest / manual


def get_file_hash(file_path, chunk_size=8192):
    """计算文件的快速哈希(MD5 + 文件大小混合指纹)"""
    file_size = os.path.getsize(file_path)
    hasher = hashlib.md5()
    hasher.update(str(file_size).encode('utf-8'))

    with open(file_path, 'rb') as f:
        while chunk := f.read(chunk_size):
            hasher.update(chunk)
    return hasher.hexdigest()


def scan_files(root_dir):
    """递归扫描所有图片文件"""
    for dirpath, _, filenames in os.walk(root_dir):
        for f in filenames:
            if Path(f).suffix.lower() in IMAGE_EXTENSIONS:
                yield Path(dirpath) / f


def find_duplicates(files):
    """多线程比对文件"""
    size_groups = defaultdict(list)
    for file in files:
        size_groups[os.path.getsize(file)].append(file)

    duplicates = defaultdict(list)
    with ThreadPoolExecutor(max_workers=THREADS) as executor:
        for size, group in size_groups.items():
            if len(group) > 1:
                hash_map = {}
                for file, file_hash in zip(group, executor.map(get_file_hash, group)):
                    hash_map.setdefault(file_hash, []).append(file)

                for files in hash_map.values():
                    if len(files) > 1:
                        # 按修改时间排序
                        files.sort(key=lambda x: os.path.getmtime(x))
                        duplicates[files[0]] = files[1:]

    return duplicates


def delete_duplicates(duplicates):
    """根据策略删除重复文件"""
    deleted_count = 0
    total_size = 0

    for orig, copies in duplicates.items():
        if DELETE_STRATEGY == "manual":
            print(f"
🔍 原始文件: {orig}")
            for i, copy in enumerate(copies, 1):
                print(f"  {i}. {copy}")

            while True:
                choice = input("输入要保留的文件编号(0=全删,回车=跳过): ").strip()
                if choice == "":
                    break
                try:
                    choice = int(choice)
                    if 0 <= choice <= len(copies):
                        to_keep = [] if choice == 0 else [copies[choice - 1]]
                        break
                except ValueError:
                    print("请输入有效数字!")
        else:
            # 自动选择保留最早或最新的文件
            to_keep = [orig] if DELETE_STRATEGY == "keep_oldest" else [copies[-1]]

        # 执行删除
        for copy in copies:
            if copy not in to_keep:
                try:
                    file_size = os.path.getsize(copy)
                    os.remove(copy)
                    print(f"🗑️ 已删除: {copy} ({file_size / 1024:.1f} KB)")
                    deleted_count += 1
                    total_size += file_size
                except Exception as e:
                    print(f"❌ 删除失败 {copy}: {e}")

    return deleted_count, total_size


def generate_html_report(duplicates, report_file):
    """修复版报告生成函数"""
    # 使用双花括号 {{}} 转义CSS中的花括号
    html = f"""<html><head><style>
        <meta charset="UTF-8">  
        body {{ font-family: Arial; margin: 20px; }}
        .group {{ border: 1px solid #ddd; margin: 15px 0; padding: 15px; border-radius: 5px; }}
        img {{ max-height: 120px; margin: 5px; border: 1px solid #eee; box-shadow: 0 0 5px rgba(0,0,0,0.1); }}
        .file-info {{ color: #666; font-size: 0.9em; margin-left: 10px; }}
        h1 {{ color: #333; border-bottom: 2px solid #eee; padding-bottom: 10px; }}
    </style></head><body>
    <h1>📝 重复文件清理报告</h1>
    <p>生成时间:{time.strftime("%Y-%m-%d %H:%M:%S")}</p>
    """
    for orig, copies in duplicates.items():
        orig_size = os.path.getsize(orig) / 1024
        html += f"""
        <div class="group">
            <h3>📌 原始文件: {orig.name}</h3>
            <p>路径: {orig} <span class="file-info">({orig_size:.1f} KB | 修改时间: {time.ctime(os.path.getmtime(orig))})</span></p>
            <img src="{orig}">
            <h4>🚨 重复文件 ({len(copies)}个):</h4>"""

        for copy in copies:
            copy_size = os.path.getsize(copy) / 1024
            html += f"""
            <div>
                <img src="{copy}">

✅✅老板的小秘密我就不展示了,更换素材展示给大家看
图片[1] - 设计狮别用PS切图了!Python像素炼丹术炸平UI流水线——老板的旅游照被我哈希去重后自动生成视频素材(附源码|可白嫖) - 宋马
图片[2] - 设计狮别用PS切图了!Python像素炼丹术炸平UI流水线——老板的旅游照被我哈希去重后自动生成视频素材(附源码|可白嫖) - 宋马
图片[3] - 设计狮别用PS切图了!Python像素炼丹术炸平UI流水线——老板的旅游照被我哈希去重后自动生成视频素材(附源码|可白嫖) - 宋马
----------------------------------------------------

👑名场面:

老板问:『你怎么知道这张洱海是重复的?』我答:『哈希值相同——就像中医望诊,病邪在表,一眼看穿!』老板:『说人话!』我:『照片DNA一模一样!您连拍了好几张!』😂
----------------------------------------------------

🎨 土味封面速搓绝招(4小时技能树碾压设计圈)

「科班设计师用PS搓1天?本怪蜀黎用Python+PPT土法炼钢,4小时搞定!
(PS:4小时是技能树点满时间,实际操作仅需0.5-1小时✅✅)

🔥 土味流水线:

1️⃣ 图片去重 → 用上文脚本哈希清洗(省去手动筛选3小时)2️⃣ 批量调色 → Python PIL滤镜流水线(“中医五行调色法”:金→冷调,木→鲜绿,水→蓝透,火→暖焦,土→棕褐)3️⃣ 布局生成 → 用PPT母板+Python自动化排版(对齐用“君臣佐使”,主图居君位,辅图列臣侧)4️⃣ 导出优化 → 批量导出4K图+视频预览(moviepy自动合成)

💪 肌肉秀点:

不用打开PS/AI,全程代码控制,重复使用一劳永逸调参数如配中药,“当归2px留白,黄芪饱和度+5”🧪老板要换风格?改两行代码直接重生一套!

😂 名场面:

老板:『这封面谁设计的?挺专业啊!』我:『Python写的,PPT拉的,中医调的——土味三合一!』老板:『???』

🌱 土到极致就是潮:

正因为“土”才能滋养药材,万物之源——代码土味,效果炸裂,专治各种设计花里胡哨!

(转发给用PS肝到天亮的设计师,教他们什么叫“降维打击”)」

✅ 附技能树时间表:

步骤 科班设计师 本怪蜀黎
图片去重 3小时 3秒
批量调色 2小时 5分钟
排版设计 4小时 1小时
导出优化 1小时 2分钟
总计 10小时 ~1小时

👉 效率提升90%,发际线保住100%!
图片[4] - 设计狮别用PS切图了!Python像素炼丹术炸平UI流水线——老板的旅游照被我哈希去重后自动生成视频素材(附源码|可白嫖) - 宋马

----------------------------------------------------

🎯结尾:

「🚀本怪蜀黎不废话,直接上源码!UI设计师学代码不是卷——是把时间留给真正的创作🎨!财务喵小姐姐已得救,设计狮小哥哥还在PS里熬夜切图——

----------------------------------------------------

🌟本蜀黎功德量化报告(走心加料版):

✅ 拯救发际线:100+条

(每避免手动手动查找一张重复图片=挽救0.01根头发💇‍♀️,按此推算已守护一片黑森林🌳)

✅老肝能量释放:200+小时

(设计圈整理素材集体提前下班⏰,陪对象/娃/猫时间++,家庭和谐度直接拉满🏡)

✅欢乐普渡:功德无量
(各位打工人看完本座与老板的欢乐故事,欢乐指数++++📈,摸鱼时间笑声溢出屏幕😂,
建议HR纳入员工心理健康福利方案)

🎯暴击式总结:

「本怪蜀黎不一定要三连,只要众生解脱——愿天下再无加班整理素材,每个打工人都能准时拥抱夕阳与爱人🌇(当然,如果顺带救了几个设计狮的单身劫,也算功德+999🧧)」(转发给团队里还在手动切图的设计狮,救救他们的黑眼圈和发际线!)」
----------------------------------------------------

⚠️ 免责声明(附因果律警告)

本代码已注入中医玄学能量,请谨慎使用:

✅ 允许白嫖,但白嫖不点赞可能导致:
下次面试官恰好问到这个算法键盘自动打出
//这里感谢冷溪虎山老中医
奶茶精准洒在刚写好的代码上 ✅ 允许商用,但商用不注明出处可能触发:
产品上线前夜突然出现递归栈溢出数据库莫名存储君臣佐使字段 ✅ 允许吐槽,但吐槽不带改进建议可能引发:
终生与边界条件相爱相杀

🚀 现在立即行动:

点赞 → 吸收本篇算法精华+怪蜀黎脑洞思维收藏 → 避免日后求医无门关注 → 接收更多「中医+代码」脑洞评论区留言 → 领取你的专属「算法药方」

如有不对之处,欢迎评论区批评指出或者留言给我!✅✅

如果这份文章帮到了你,请点赞、收藏、关注三连!你们的支持,就是我继续‘炼丹’的动力🏆🏆!

💡✨本文采用【开源共享】协议!欢迎转载、洗稿、甚至做成视频!只需保留原作者署名(ERP老兵-冷溪虎山),让我们一起把跨界技术的快乐传递出去!。
让我们一起把快乐和效率带给更多人!,缺爆款素材的兄弟姐妹可以关注私我,保证你用不完的爆款素材🚀🚀

----------------------------------------------------

Python工具箱系列上线,VIP轮换解锁,复制粘贴就能用✅✅:

财务小姐姐秃力觉醒!别再用Excel手抠发票了!Python暴力解析PDF,文件名金额自动追杀差额(附源码|白嫖救发)

Python抓虫笔记:零宽空格(zwsp)隐形乱码?3分钟学会 揪出所有“文字幽灵”!(附清洗工具实战)

路径“如人体经络?Python/JS/Java/Go四语言“针灸术”——通不了算我输!附源码白嫖|职场生存指南|专治老板“文件找不到”咒术
----------------------------------------------------

✨碰到 其他卡顿问题| 其他数据抓取"正则"匹配问题? JetBrains 全家桶性能优化 ,点击以下链接👇👇直达其他爆款指南:

1.IDEA 调参高手都在偷学的配置!9GB 堆内存+OpenGL 渲染优化全公开(附注释版 vmoptions)

2.全网 10 万 Python 开发者在找的 vmoptions 配置!PyCharm 性能炸裂的秘密在这

3.WebStorm 调参高手都在用的配置!续集:IDEA/PyCharm 飞升后,前端 IDE 性能炸裂的秘密

4.GoLand 调参高手都在用的配置!续集:WebStorm 飞升后,Go 开发 IDE 性能炸裂的秘密

5.CLion 调参高手都在用的配置!续集:GoLand 飞升后,C/C++ 开发 IDE 性能炸裂的秘密

6.DataGrip 性能狂暴调优!2025 最新 JVM 参数+数据库索引加速配置,实测查询效率飙升

7.正则“|“表达式“?别再死记硬背了:17年非科班老炮 用正则速通秘籍,把你喂到饱!面试必备!(附记忆口诀->映射表)

8.程序员用国际正则征服全球文本!从ASCII到Unicode的玄学调试指南 面试高频!(附四大语言Python/JS/Java/Go支持对比+中医(HIS)映射表)

9.Java反射如中医“望闻问切”?HIS系统开发必备魔法逆向术!(附源码/面试高频/最小原型实战)

10.一群程序员跑去学中医,竟然是为了治好“祖传屎山”版的HIS系统?(附编程术语映射列表)

PS:按顺序看效果更佳!从 Java 到 Python,从 Web 到 C/C++,再到数据库——一套逻辑通吃 JetBrains 全家桶!

转发给团队里还在用默认配置的同事,救救他们的电脑和头发!"

“💡 不用东找西找——你要的「性能调优×数据抓取」爆款攻略,这里全都有!点击↑↑↑快速查漏补缺!”

🚀各位兄弟姐妹,缺素材的去"爱给网"我的主页下载,海量素材等你来薅:
© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容