最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python通過計算圖片MD5值實現(xiàn)圖片去重

 更新時間:2026年05月22日 08:14:24   作者:detayun  
這篇文章主要為大家詳細(xì)介紹了Python如何通過MD5實現(xiàn)圖片去重的3種計算方式并進(jìn)行了對比,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下

一文搞懂:從 base64 到二進(jìn)制,3種方式計算圖片MD5,附完整去重方案

前言

在日常開發(fā)中,我們經(jīng)常遇到這樣的場景:

場景需求
圖片上傳去重判斷圖片是否已經(jīng)存在
本地文件對比判斷文件是否被修改
爬蟲去重避免下載重復(fù)圖片
緩存管理用MD5作為緩存key

MD5 就是解決這類問題的神器!那么在 Python 中,如何計算一張圖片的 MD5 值呢?

今天這篇文章,我會從 最簡單到最完整,帶你掌握所有方法 

一、MD5 是什么?(30秒理解)

MD5 是一種哈希算法,可以把任意長度的數(shù)據(jù),轉(zhuǎn)換成一個 32位的十六進(jìn)制字符串。

原圖(1MB)  →  MD5  →  "a1b2c3d4e5f6..."(32個字符)

它的特點:

特性說明
相同輸入 → 相同輸出同一張圖片,MD5永遠(yuǎn)一樣
不同輸入 → 不同輸出不同圖片,MD5幾乎肯定不同
單向不可逆無法從MD5還原出原圖
有極小碰撞概率實際開發(fā)中可以忽略

一句話總結(jié):MD5 就是圖片的"指紋"!

二、3種計算方式(由淺入深)

假設(shè)我們有一張 base64 圖片字符串:

base64_str = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="

方式一:直接對 base64 字符串算 MD5(最簡單)

import hashlib

def md5_from_base64(base64_str):
    clean_str = base64_str.strip().replace('\n', '').replace(' ', '')
    return hashlib.md5(clean_str.encode()).hexdigest()

md5 = md5_from_base64(base64_str)
print(md5)  # a1b2c3d4e5f6...
優(yōu)點缺點
一行代碼搞定base64有空格/換行會導(dǎo)致誤判
不需要解碼data:image/png;base64, 前綴會出錯

適合:快速驗證,對精度要求不高的場景

方式二:對原始二進(jìn)制算 MD5(? 推薦)

import hashlib
import base64

def md5_from_binary(base64_str):
    # 1. base64 → 二進(jìn)制
    image_data = base64.b64decode(base64_str)
    # 2. 二進(jìn)制 → MD5
    return hashlib.md5(image_data).hexdigest()

md5 = md5_from_binary(base64_str)
print(md5)
優(yōu)點缺點
最準(zhǔn)確,不受編碼影響需要多一步解碼
自動忽略空格/換行-
工業(yè)級標(biāo)準(zhǔn)做法-

????? 這是最推薦的方式!

方式三:從文件路徑計算 MD5

如果你的圖片是本地文件,根本不需要 base64:

import hashlib

def md5_from_file(file_path):
    md5 = hashlib.md5()
    with open(file_path, 'rb') as f:
        for chunk in iter(lambda: f.read(8192), b''):
            md5.update(chunk)
    return md5.hexdigest()

md5 = md5_from_file('photo.jpg')
print(md5)
優(yōu)點缺點
最快,不用解碼只能用于本地文件
內(nèi)存友好(分塊讀?。?/td>-
支持大文件(幾GB都行)-

????? 本地文件首選這個!

三、踩坑指南(非常重要?。?/h2>

坑1:base64 帶前綴

很多地方的 base64 長這樣:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...

必須去掉前綴!

def extract_base64(s):
    if ',' in s:
        return s.split(',', 1)[1]  # 只分割一次
    return s

clean_b64 = extract_base64(base64_str)
md5 = md5_from_binary(clean_b64)

坑2:base64 有空格/換行

不同來源的 base64 格式不一樣:

# 來源A(干凈)
"iVBORw0KGgoAAAANSUhEUg..."

# 來源B(帶換行)
"iVBORw0KGgoAAAANSUhEUg...
AAAAAAAAAAAAAAAAA..."

解決辦法:解碼時自動忽略!(方式二天然支持)

坑3:肉眼看一樣,但MD5不同

比如:

  • 一張圖被重新壓縮了(質(zhì)量從90%降到80%)
  • PNG轉(zhuǎn)JPG再轉(zhuǎn)PNG
  • 改了一個像素

這時候 MD5 會不同,但你可能覺得是"同一張圖"。

解決方案:使用感知哈希(pHash)

# pip install imagehash
import imagehash
from PIL import Image
import io
import base64

def phash_from_base64(base64_str):
    image_data = base64.b64decode(base64_str)
    img = Image.open(io.BytesIO(image_data))
    return str(imagehash.phash(img))  # 返回感知哈希值

# 即使壓縮過,pHash 也可能相同!
對比MD5pHash
精確匹配??
壓縮后識別??
速度極快較慢
使用場景去重/校驗相似圖搜索

四、完整實戰(zhàn):圖片去重管理器

下面是一個可以直接用的 圖片去重類

import hashlib
import base64
import json

class ImageDeduplicator:
    """圖片去重管理器"""
    
    def __init__(self):
        self.seen = {}  # {md5: count} 記錄見過的圖片
    
    def get_md5(self, base64_str):
        """計算圖片MD5(推薦方式)"""
        # 去除前綴
        if ',' in base64_str:
            base64_str = base64_str.split(',', 1)[1]
        # base64 → 二進(jìn)制 → MD5
        image_data = base64.b64decode(base64_str)
        return hashlib.md5(image_data).hexdigest()
    
    def check(self, base64_str, label=""):
        """
        檢查圖片是否重復(fù)
        返回: (是否重復(fù), md5值)
        """
        md5 = self.get_md5(base64_str)
        
        if md5 in self.seen:
            self.seen[md5] += 1
            return True, md5, self.seen[md5]
        else:
            self.seen[md5] = 1
            return False, md5, 1
    
    def save(self, filepath='seen_images.json'):
        """保存去重記錄"""
        with open(filepath, 'w') as f:
            json.dump(self.seen, f, indent=2)
    
    def load(self, filepath='seen_images.json'):
        """加載去重記錄"""
        try:
            with open(filepath, 'r') as f:
                self.seen = json.load(f)
        except FileNotFoundError:
            self.seen = {}


# ==================== 使用示例 ====================

dedup = ImageDeduplicator()

# 模擬3張圖片(第1張和第3張是同一張)
images = [
    ("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", "圖片A"),
    ("data:image/png;base64,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "圖片B"),
    ("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", "圖片A(重復(fù))"),
]

for b64, name in images:
    is_dup, md5, count = dedup.check(b64, name)
    status = "?? 重復(fù)" if is_dup else "? 新圖片"
    print(f"{name}: {status} | MD5: {md5} | 已出現(xiàn){count}次")

# 保存記錄
dedup.save()

運(yùn)行結(jié)果

圖片A: ? 新圖片 | MD5: a1b2c3d4e5f6... | 已出現(xiàn)1次
圖片B: ? 新圖片 | MD5: f6e5d4c3b2a1... | 已出現(xiàn)1次
圖片A(重復(fù)): ?? 重復(fù) | MD5: a1b2c3d4e5f6... | 已出現(xiàn)2次

五、總結(jié)對比

方式代碼量準(zhǔn)確度推薦場景
對base64字符串算MD5? 最少???快速驗證
對二進(jìn)制算MD5 ??? 少?????所有場景(推薦)
從文件路徑算MD5?? 少?????本地文件處理
pHash感知哈希???? 多?????相似圖識別

六、一句話總結(jié)

  • 推薦做法:base64 → 解碼為二進(jìn)制 → hashlib.md5() → hexdigest()
  • 記住去前綴:base64_str.split(',')[1]
  • 需要相似圖識別?用 imagehash.phash() 代替 MD5

到此這篇關(guān)于Python通過計算圖片MD5值實現(xiàn)圖片去重的文章就介紹到這了,更多相關(guān)Python圖片去重內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

视频| 明水县| 乳山市| 淳化县| 古蔺县| 滨海县| 靖宇县| 湾仔区| 巧家县| 鱼台县| 五河县| 乾安县| 油尖旺区| 大连市| 永胜县| 兴城市| 北票市| 禹州市| 乌拉特中旗| 定结县| 全南县| 巴东县| 三原县| 东辽县| 南澳县| 女性| 凌海市| 安福县| 彰武县| 栾城县| 射阳县| 明光市| 郯城县| 江川县| 白水县| 博兴县| 宁安市| 富川| 马尔康县| 堆龙德庆县| 镇巴县|