【问题标题】:What is the best method to remove duplicate image files from your computer?从计算机中删除重复图像文件的最佳方法是什么?
【发布时间】:2020-09-18 17:22:03
【问题描述】:

我的 Windows 计算机上有很多重复的图像文件,它们位于不同的子文件夹和不同的文件名。

您会推荐什么 Python 脚本或免费软件程序来删除重复项?

(我读过this 类似的问题,但那里的海报询问具有不同文件大小的视觉重复。我的是具有不同文件名的完全相同的重复。)

【问题讨论】:

  • 请记住,即使所有像素都相同,它们仍然可能具有不同的 EXIF 信息(由在某个阶段处理图像的程序修改),这会对大多数当前提出的解决方案造成问题。

标签: windows python deduplication image-processing


【解决方案1】:

不要依赖 MD5 和。

MD5 和不是检查重复项的可靠方法,它们只是检查差异的一种方法。

使用 MD5 查找 可能的 候选 个重复项,然后为每对共享一个 MD5

  1. 打开两个文件
  2. 在这些文件中向前搜索,直到其中一个不同。

看到我被那些用天真的方法来提交重复身份的人所否决,如果你要完全依赖哈希算法,看在上帝的份上,使用更严格的东西,比如 SHA256 或 SHA512 ,至少您可以通过检查更多位将概率降低到合理的程度。 MD5 在碰撞条件下非常弱。

我还建议人们在这里阅读标题为“文件检查”的邮件列表:http://london.pm.org/pipermail/london.pm/Week-of-Mon-20080714/thread.html

如果你说“MD5 可以唯一地识别所有文件”,那么你有一个逻辑错误。

给定一系列值,长度从 40,000 字节到 100,000,000,000 字节不等,该范围内可用的组合总数大大超过了 MD5 表示的可能值的数量,长度仅为 128 位。

仅用 2^128 个组合表示 2^100,000,000,000 个组合?我认为这不太可能。

最简单的方法

清除重复项的最简单、最快的方法如下。

  1. 按大小:大小不同的文件不能完全相同。这需要很少的时间,因为它甚至不必打开文件。
  2. 通过 MD5 :具有不同 MD5/Sha 值的文件不能相同。这需要更长的时间,因为它必须读取文件中的所有字节并对它们执行数学运算,但它使多重比较更快。
  3. 上述差异失败:对文件进行逐字节比较。这是一个执行起来很慢的测试,这就是为什么它要等到所有其他消除因素都被考虑之后再进行。

Fdupes 这样做。您应该使用使用相同标准的软件。

【讨论】:

  • 硬盘驱动器更可能会神奇地破坏图像,而不是 MD5 会发生碰撞。 “仅用 2^128 个组合表示 2^100,000,000,000 个组合” - 我同意你的观点。如果他有 2^100,000,000,000 张图片,MD5(或几乎任何哈希算法)都会很糟糕。
  • 没有没有保证,只是不太可能。它不是不可能的。很有可能有 10 个文件相互冲突,但完全不同。这不太可能发生,但可能会发生,因此您必须对其进行测试。
  • 文件大小,然后是 MD5,然后是逐字节检查。
  • @Kent - 我 100% 同意你的看法。忽视某事是一种懒惰,因为它非常不可能,即使像我们所说的那样不太可能。如果我的一些数据被破坏了,我会很生气,因为编写程序的人认为有些东西不太可能打扰编码。
【解决方案2】:

它是安装了 Cygwin 的 unix(包括 linux)操作系统或 Windows 上的单行:

find . -type f -print0 | xargs -0 shasum | sort |
  perl -ne '$sig=substr($_, 0, 40); $file=substr($_, 42); \
    unlink $file if $sig eq $prev; $prev = $sig'

如果您知道没有故意制造的碰撞,则可以使用 md5sum(大约快 50%)(与找到一个自然发生的 md5 碰撞相比,您赢得 10 个主要彩票的机会更大。)

如果您想查看所有 dup 而不是删除它们,只需将 unlink $file 部分更改为 print $file, "\n"

【讨论】:

  • 您也可以使用 -print0 和 xargs-0 来捕捉空格,但 find 还有一个 -exec 选项在这里很有用: find 。 -type f -exec shasum {} \; | sort ... 另外:您不应该使用 @F (-a) 因为它不适用于空格。改用 substr。
  • 好电话,geocar。用您的建议更新了答案。
  • “如果您知道没有故意制造的碰撞,可以使用 md5sum(大约快 50%)” - 完全正确
【解决方案3】:

我在 Unix 系统上使用过fdupes(用 C 语言编写)和freedups(Perl),它们也可能在 Windows 上工作;还有 similar ones 声称可以在 Windows 上工作:dupmergeliten(用 Python 编写)等。

【讨论】:

  • Perl 和 Python 软件应该在 Windows 和 *nix 系统上同样工作,假设文件系统的细节无关紧要。
【解决方案4】:

要删除 Windows 上的重复图像,请查看 DupliFinder. 它可以按名称、大小和实际图像信息等各种标准比较图片。

有关删除重复文件的其他工具,请查看此 Lifehacker article.

【讨论】:

    【解决方案5】:

    一个选项可以是Dupkiller

    DupKiller 是搜索和删除计算机上重复或类似文件的最快、最强大的工具之一。复杂的算法,内置于其搜索机制,执行高结果 - 快速文件搜索。许多选项允许灵活地自定义搜索。

    【讨论】:

      【解决方案6】:

      一种扫描重复图像('.jpg'、'.png'、'.gif'、'.jpeg'、'.webp'、'.tiff'、'.psd'、'.raw ','.bmp','.heif','indd','.svg' 格式支持):

      • 通过 SHA256 哈希检查
      • 用于选择要删除的文件和要扫描的驱动器的 GUI 对话框
      • 请稍候对话框
      • 隐藏 Powershell 控制台
      • 可能会很慢
      $sig=@'
      public static void ShowConsoleWindow(int state)
      {
        var handle = GetConsoleWindow();
        ShowWindow(handle,state);
      }
      [System.Runtime.InteropServices.DllImport("kernel32.dll")]
      static extern IntPtr GetConsoleWindow();
      [System.Runtime.InteropServices.DllImport("user32.dll")]
      static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
      '@
      $hc=Add-Type -mem $sig -name Hide -Names HideConsole -Ref System.Runtime.InteropServices -Pas
      $hc::ShowConsoleWindow(0)
      [console]::title="Duplicate Image Scanner (c) Wasif Hasan | Sep 2020"
      $eXt=@('.jpg','.png','.gif','.jpeg','.webp','.tiff','.psd','.raw','.bmp','.heif','indd','.svg')
      @('system.windows.forms','system.drawing')|%{add-type -as $_}
      $s=[windows.forms.form]::new();$s.size=[drawing.size]::new(400,850);$s.StartPosition="CenterScreen";$s.Text="Select drives to scan"
      $drives=gdr -p "FileSystem"|select -eXp name
      $top=20;$left=50;$drives|%{
      $c=$_.split(" ")-join"_";$top += 20
      iex "`$$($c) = New-Object System.Windows.Forms.CheckBox;`$$($c).Top = $($top);`$$($c).Left = $($left);`$$($c).Anchor='Left,Top';`$$($c).Parent='';`$$($c).Text='$($_)';`$$($c).Autosize=`$true;if('$_' -in `$drives){`$$c.Checked=`$true};`$s.Controls.Add(`$$c)"
      }
      $ok=New-Object System.Windows.Forms.Button;$ok.Text='OK';$ok.Top=770;$ok.Left=290
      $ok.add_click({$s.Close()});$s.Controls.AddRange($ok)
      $sa=New-Object System.Windows.Forms.Button;$sa.Text='Select All';$sa.Top=770;$sa.Left=200
      $sa.add_click({$s.Controls|?{($_.Checked) -or !($_.Checked)}|%{try{$_.Checked=$True}catch{}}});$s.Controls.AddRange($sa)
      $null=$s.ShowDialog()
      $choices=$s.Controls|?{$_.Checked}|select -eXp Text
      $i=0;$choices|%{$choices[$i]=$_+':\';$i++}
      $f=[windows.forms.form]::new();$f.Size=[drawing.size]::new(600,100);$f.StartPosition="CenterScreen";$f.Text="Please wait"
      $l=[windows.forms.label]::new();$l.Text="Please wait until the scan is complete........";$l.Font="Segoe UI,16";$l.AutoSize=$true;$f.Controls.AddRange($l)
      $null=$f.ShowDialog()
      $files=@();$hCols=@();$choices|%{
       dir $_ -r|?{$_.eXtension-in$eXt}|%{
         $h=get-filehash $_.fullname -a 'SHA256'|select -eXp hash
         if($h-in$hCols){$files+=$_.fullName}else{$hCols+=$h}
      }};$f.Close()
      $del=$files|ogv -t "Duplicate images (Hold CTRL and select the ones to delete)" -p
      $del|%{rm "$_" -fo}
      [windows.forms.messagebox]::Show("Thanks for using!","Duplicate image scanner","OK","Information")
      

      【讨论】:

        【解决方案7】:

        尝试使用分叉项目DeadRinger,而不是 DupliFinder。我们修复了原始项目中的大量错误,添加了许多新功能,并显着提高了性能。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-01
          • 2012-05-19
          • 2010-10-16
          • 2015-08-16
          • 2016-10-24
          • 2023-04-02
          相关资源
          最近更新 更多