移动和备份我的照片集几次后,我有几张重复的照片,各种文件夹中的不同文件名分散在我的电脑上。所以我想我会写一个快速的CF(9)页面来找到重复项(然后可以稍后添加代码以允许我删除它们)。
我有几个问题: -
目前我只是使用文件大小来匹配图像文件,但我认为匹配的EXIF数据或图像文件二进制的匹配哈希会更可靠吗?
我把这些代码捆绑在一起,但是如何才能在网络外部搜索?
有更好的方法吗?
P
<cfdirectory
name="myfiles"
directory="C:\ColdFusion9\wwwroot\images\photos"
filter="*.jpg"
recurse="true"
sort="size DESC"
type="file" >
<cfset matchingCount=0>
<cfset duplicatesFound=0>
<table border=1>
<cfloop query="myFiles" endrow="#myfiles.recordcount#-1">
<cfif myfiles.size is myfiles.size[currentrow + 1]>
<!---this file is the same size as the next row--->
<cfset matchingCount = matchingCount + 1>
<cfset duplicatesFound=1>
<cfelse>
<!--- the next file is a different size --->
<!--- if there have been matches, display them now --->
<cfif matchingCount gt 0>
<cfset sRow=#currentrow#-#matchingCount#>
<cfoutput><tr>
<cfloop index="i" from="#sRow#" to="#currentrow#">
<cfset imgURL=#replace(directory[i], "C:\ColdFusion9\wwwroot\", "http://localhost:8500/")#>
<td><a href="#imgURL#\#name[i]#"><img height=200 width=200 src="#imgURL#\#name[i]#"></a></td>
</cfloop></tr><tr>
<cfloop index="i" from="#sRow#" to="#currentrow#">
<td width=200>#name[i]#<br>#directory[i]#</td>
</cfloop>
</tr>
</cfoutput>
<cfset matchingCount = 0>
</cfif>
</cfif>
</cfloop>
</table>
<cfif duplicatesFound is 0><cfoutput>No duplicate jpgs found</cfoutput></cfif>
答案 0 :(得分:3)
这是非常有趣的任务,所以我决定尝试一下。
首先,我的笔记本电脑上有4GB内存,2x2.26Ghz CPU和SSD的一些测试结果:1,143张图像,总计263.8MB。
ACF9:重复8次,耗时~2.3秒
Railo 3.3:8重复,花了~2.0秒(耶!)
我使用了来自this SO answer的精彩提示来选择最佳的哈希选项。
所以,这就是我所做的:
<cfsetting enablecfoutputonly="true" />
<cfset ticks = getTickCount() />
<!--- this is great set of utils from Apache --->
<cfset digestUtils = CreateObject("java","org.apache.commons.codec.digest.DigestUtils") />
<!--- cache containers --->
<cfset checksums = {} />
<cfset duplicates = {} />
<cfdirectory
action="list"
name="images"
directory="/home/trovich/images/"
filter="*.png|*.jpg|*.jpeg|*.gif"
recurse="true" />
<cfloop query="images">
<!--- change delimiter to \ if you're on windoze --->
<cfset ipath = images.directory & "/" & images.name />
<cffile action="readbinary" file="#ipath#" variable="binimage" />
<!---
This is slow as hell with any encoding!
<cfset checksum = BinaryEncode(binimage, "Base64") />
--->
<cfset checksum = digestUtils.md5hex(binimage) />
<cfif StructKeyExists(checksums, checksum)>
<!--- init cache using original on 1st position when duplicate found --->
<cfif NOT StructKeyExists(duplicates, checksum)>
<cfset duplicates[checksum] = [] />
<cfset ArrayAppend(duplicates[checksum], checksums[checksum]) />
</cfif>
<!--- append current duplicate --->
<cfset ArrayAppend(duplicates[checksum], ipath) />
<cfelse>
<!--- save originals only into the cache --->
<cfset checksums[checksum] = ipath />
</cfif>
</cfloop>
<cfset time = NumberFormat((getTickcount()-ticks)/1000, "._") />
<!--- render duplicates without resizing (see options of cfimage for this) --->
<cfoutput>
<h1>Found #StructCount(duplicates)# duplicates, took ~#time# s</h1>
<cfloop collection="#duplicates#" item="checksum">
<p>
<!--- display all found paths of duplicate --->
<cfloop array="#duplicates[checksum]#" index="path">
#HTMLEditFormat(path)#<br/>
</cfloop>
<!--- render only last duplicate, they are the same image any way --->
<cfimage action="writeToBrowser" source="#path#" />
</p>
</cfloop>
</cfoutput>
显然,您可以轻松使用duplicates
数组来查看结果和/或运行一些清理工作。
玩得开心!
答案 1 :(得分:0)
我建议将检查代码拆分为只接受文件名的函数。
然后使用全局结构来检查重复项,键是“size”或“size_hash”,值可以是一个包含与该键匹配的所有文件名的数组。
在所有不同目录中的所有jpeg文件上运行该函数,然后扫描结构并报告其数组中包含多个文件的所有条目。
如果您想在webroot外部显示图片,可以通过&lt; cfcontent file =“#filename#”type =“image / jpeg”&gt;