指定フォルダ以下の画像(種別問わず)をすべてピックアップして、それぞれMD5チェックサムを計算し、重複しているものをピックアップしてデータとして出力するAppleScriptです。実行にはScript Debuggerを必要とします。今後は、ScriptableなライブラリをXcodeで1本作って、そこにAppleScriptから呼び出すのに便利なFrameworkを突っ込みまくるようにするのかも?
–> Download Script Bundle within framework and library
前バージョンのScriptでは指定フォルダ直下の画像だけをピックアップするようになっていました、Spotlight検索でサブディレクトリ以下もすべて画像収集するように変更し、本Scriptだけで重複画像のブラウズができるようになっています。NSOutlineView+NSImageでブラウズするダイアログの部品はedama2さんから提供していただいています。
AppleScript名:指定フォルダ以下の画像のMD5チェックサムを求めて、重複しているものをピックアップしてダイアログでプレビュー_v4.scptd |
— Created 2015-10-01 by Takaaki Naganoya — Modified 2015-10-01 by Shane Stanley–With Cocoa-Style Filtering — Modified 2018-12-01 by Takaaki Naganoya — Modified 2024-12-19 by Takaaki Naganoya — Modified 2025-01-01 by Takaaki Naganoya — Modified 2025-01-02 by Takaaki Naganoya use AppleScript use scripting additions use framework "Foundation" use framework "AppKit" use framework "md5Lib" –https://github.com/JoeKun/FileMD5Hash use outImageV : script "visLib" –NSOUtlineView+NSImageView Lib by edama2 use mdLib : script "Metadata Lib" version "2.0.0" property |NSURL| : a reference to current application’s |NSURL| property NSArray : a reference to current application’s NSArray property NSPredicate : a reference to current application’s NSPredicate property NSCountedSet : a reference to current application’s NSCountedSet property NSURLTypeIdentifierKey : a reference to current application’s NSURLTypeIdentifierKey property NSString : a reference to current application’s NSString property NSFileManager : a reference to current application’s NSFileManager property NSMutableArray : a reference to current application’s NSMutableArray property NSSortDescriptor : a reference to current application’s NSSortDescriptor script spd property fList : {} property fRes : {} property md5List : {} property fmdList : {} property dupRes : {} property outList : {} end script set aFol to POSIX path of (choose folder) –set aFol to POSIX path of (path to pictures folder) set (fRes of spd) to mdLib’s searchFolders:{aFol} searchString:("(kMDItemContentTypeTree CONTAINS %@)") searchArgs:{"public.image"} –すべての画像のMD5チェックサムを計算 set (md5List of spd) to {} set (fmdList of spd) to {} repeat with i in (fRes of spd) set j to contents of i set md5Res to (current application’s FileHash’s md5HashOfFileAtPath:(j)) as string set the end of (md5List of spd) to md5Res set the end of (fmdList of spd) to {filePath:j, md5:md5Res} end repeat –チェックサムが重複している画像を取り出す set fmdArray to NSArray’s arrayWithArray:(fmdList of spd) set (dupRes of spd) to returnDuplicatesOnly((md5List of spd)) of me set (outList of spd) to {} set procMDs to {} set aRecord to {} repeat with i in (dupRes of spd) set j to contents of i if j is not in procMDs then set aRes to filterDictArrayByLabel(fmdArray, "md5 == ’" & j & "’") of me set tmpMD5 to filePath of (first item of aRes) set tmpRes to {} repeat with ii in aRes set jj to contents of ii set idSrcURL to (current application’s NSURL’s fileURLWithPath:(filePath of jj)) set the end of tmpRes to {|name|:idSrcURL’s lastPathComponent(), fileURL:idSrcURL, isLeaf:true} end repeat set aRec to {|name|:j, fileRes:"", isLeaf:false, children:tmpRes} set aRecord’s end to aRec set the end of procMDs to j set the end of (outList of spd) to aRec end if end repeat –OutlineView+ ImageViewでダイアログ表示 set mainMes to "重複画像一覧" set subMes to "指定フォルダ以下の重複画像は以下のとおりです" set aRes to outImageV’s alert:mainMes informativeText:subMes treeData:(outList of spd) isExpand:true –リストに入れたレコードを、指定の属性ラベルの値で抽出 on filterDictArrayByLabel(aArray, aPredicate as string) –抽出 set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicate set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate return filteredArray end filterDictArrayByLabel –指定フォルダ以下のすべてのファイルを再帰で取得 on retFullpathsWithinAFolderWithRecursive(aFol) set anArray to NSMutableArray’s array() set aPath to NSString’s stringWithString:aFol set dirEnum to NSFileManager’s defaultManager()’s enumeratorAtPath:aPath repeat set aName to (dirEnum’s nextObject()) if aName = missing value then exit repeat set aFullPath to aPath’s stringByAppendingPathComponent:aName anArray’s addObject:(aFullPath as string) end repeat return anArray as list end retFullpathsWithinAFolderWithRecursive –Alias listから指定UTIに含まれるものをPOSIX pathのリストで返す on filterAliasListByUTI(aList, targUTI) set newList to {} repeat with i in aList set j to POSIX path of i set tmpUTI to my retUTIfromPath(j) set utiRes to my filterUTIList({tmpUTI}, targUTI) if utiRes is not equal to {} then set the end of newList to j end if end repeat return newList end filterAliasListByUTI –指定のPOSIX pathのファイルのUTIを求める on retUTIfromPath(aPOSIXPath) set aURL to |NSURL|’s fileURLWithPath:aPOSIXPath set {theResult, theValue} to aURL’s getResourceValue:(reference) forKey:NSURLTypeIdentifierKey |error|:(missing value) if theResult = true then return theValue as string else return theResult end if end retUTIfromPath –UTIリストが指定UTIに含まれているかどうか演算を行う on filterUTIList(aUTIList, aUTIstr) set anArray to NSArray’s arrayWithArray:aUTIList set aPred to NSPredicate’s predicateWithFormat_("SELF UTI-CONFORMS-TO %@", aUTIstr) set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list return bRes end filterUTIList on returnDuplicatesOnly(aList as list) set aSet to NSCountedSet’s alloc()’s initWithArray:aList set bList to (aSet’s allObjects()) as list set dupList to {} repeat with i in bList set aRes to (aSet’s countForObject:i) if aRes > 1 then set the end of dupList to (contents of i) end if end repeat return dupList end returnDuplicatesOnly |
More from my site
(Visited 2 times, 1 visits today)