Digitalfotografie: Überzählige Bilddateien löschen

Vor allem der, der mit einer digitalen Spiegelreflexkamera (DSLR) arbeitet, wird dieses Problem sicher aus seiner Anfangszeit kennen. Dieser Kameratyp kann üblicherweise zwei Dateiformate aufzeichnen:

Wenn man den Arbeitsaufwand für schnelle Ergebnisse reduzieren möchte, kann man von vielen Kameras je Bild auch ein RAW und ein JPEG erstellen lassen, eine Methode, die für Einsteiger durchaus empfehlenswert ist: Auch wenn man mit RAW noch nichts anfangen kann, hält sich der Amateur alle Optionen offen.

Irgendwann kommt aber der Zeitpunkt, ab dem man die Festplatte aufräumen muss. Dann empfiehlt es sich bei großen Beständen die geringwertigeren JPEGs zu Gunsten der RAWs zu entsorgen, auch wenn ein gelöschtes JPEG deutlich weniger Platz freigibt, als die zugehörige RAW-Dateien.

Um diese Arbeit zu erleichtern, habe ich mir ein kleines Skript in VBS (nur für Windows) geschrieben, das auch noch konfiguriert werden kann:


Option Explicit
On Error Resume Next

Dim FS, Liste, Nr, Verzeichnis, Objekt, EinzelBestaetigung
Dim RawDateiTypenListe, BildDateiTypenListe, Anzahl, AnzahlBytes

Set Liste    = WScript.Arguments
Set FS       = CreateObject("Scripting.FileSystemObject")


' Dateiendungen der Original-RAW-Dateien
' Immer mit . vor der Endung!!
RawDateiTypenListe = array(".CR2", ".NEF", ".CRW")  ' Liste kann mit , erweitert werden

' Dateiendungen der zu löschenden Klone (sofern vorhanden)
' Immer mit . vor der Endung!!
BildDateiTypenListe = array(".jpg", ".Jpeg", ".TIF")

Anzahl = 0
AnzahlBytes = 0

EinzelBestaetigung = MsgBox("Mit Einzelbestätigung?", _
                 vbYesNoCancel, "Doppelte Dateien löschen")

If EinzelBestaetigung = vbCancel Then WScript.Quit
EinzelBestaetigung = (EinzelBestaetigung = vbYes)


If Liste.Count > 0 Then
    ' Then wird ausgeführt, wenn aus dem Explorer Dateien
    ' mit Drag & Drop auf diese Skript-Datei gezogen wurden

    For Nr = 0 To Liste.Count - 1
        DateiSystemDurchsuchen Liste(Nr)
    Next

Else
    ' Else wird ausgeführt, wenn dieses Skript gestartet
    ' wurde, ohne dass Argumente übergeben wurden

    ' Ruft einen Dialog von Windows auf, mit dem eine
    ' Datei oder ein Ordner ausgewählt werden kann
    Set Verzeichnis = CreateObject("Shell.Application") _
        .BrowseForFolder(0, "Datei oder Verzeichnis wählen" _
        , &H4011, 17)

    ' Skript beenden, falls im Dialog die Schaltfläche
    ' Abbrechen gedrückt wurde
    If TypeName(Verzeichnis) = "Nothing" Then WScript.Quit

    Objekt = LCase(TypeName(Verzeichnis.ParentFolder))

   If (Objekt = "folder") Or (Objekt = "folder2") Or _
        (Objekt = "folder3") Then
       
        For Each Objekt In Verzeichnis.ParentFolder.Items
            If Objekt.Name = Verzeichnis.Title Then Exit For
        Next
    End If

    DateiSystemDurchsuchen Objekt.Path
End If

MsgBox Anzahl & " Dateien gelöscht" & vbNewLine & AnzahlBytes  & " kB"

'*** Ende des Skripts


' ---------------------------------------------------------- '
' Rekursives Unterprogramm um das Dateisystem zu durchsuchen
' ---------------------------------------------------------- '

Private Sub DateiSystemDurchsuchen(Pfad)
    Dim Ordner, UnterOrdner, Datei

    If FS.FolderExists(Pfad) Then
        ' Then: Falls Ordner übergeben wurde
        Set Ordner = FS.GetFolder(Pfad)

        ' Papierkorb nicht bearbeiten
        If LCase(Ordner.Name) = "recycled" Then Exit Sub

        ' Funktion Bearbeiten() für Ordner aufrufen
        If Not Bearbeiten(Ordner, False) Then Exit Sub

        ' Alle Dateien im Ordner bearbeiten
        For Each Datei In Ordner.Files
            ' Prozedur Bearbeiten() für Dateien aufrufen
            If Not Bearbeiten(Datei, True) Then Exit For
        Next

         ' Alle Unterordner rekursiv bearbeiten
        For Each UnterOrdner In Ordner.SubFolders
            ' Einstieg In die Rekursion
            DateiSystemDurchsuchen UnterOrdner
        Next

    ElseIf FS.FileExists(Pfad) Then
        ' Else: Falls eine einzelne Datei übergeben wurde
        Bearbeiten FS.GetFile(Pfad), True
    End If
End Sub


' Funktion, welche die Dateinamen vergleicht
Private Function Bearbeiten(Datei, IstDatei)
    Dim RawDateiTyp, BildDateiTyp, NameKlon
    Bearbeiten = True ' True = Programm nicht abbrechen
    If IstDatei Then
        For Each RawDateiTyp In RawDateiTypenListe
            If UCase(Right(Datei.Name, Len(RawDateiTyp))) = _
                                        UCase(RawDateiTyp) Then
                For Each BildDateiTyp In BildDateiTypenListe
                    NameKlon = Left(Datei.Path, Len(Datei.Path) _
                                        - Len(RawDateiTyp)) & BildDateiTyp
                    If FS.FileExists(NameKlon) Then
                        If EinzelBestaetigung Then
                            Select Case MsgBox ("Pfad: " & _
                                        Datei.ParentFolder & "\" & _
                                        vbNewLine  & UCase(Datei.Name) & _
                                        " (" & Datei.Size & ") -> behalten" & _
                                        vbNewLine & UCase(Left(Datei.Name, _
                                        Len(Datei.Name) - Len(RawDateiTyp)) & _
                                        BildDateiTyp) & " (" & _
                                        FS.GetFile(NameKlon).Size & _
                                        ") -> löschen", vbYesNoCancel)
                                Case vbYes:    LoescheDatei(NameKlon)
                                Case vbCancel
                                        Bearbeiten = False ' Ohne Aktion abbrechen
                            End Select
                        Else LoescheDatei(NameKlon)
                        End If
                    End If
                Next
            End If
        Next
    End If

End Function

Private Sub LoescheDatei(NameDatei)
    Anzahl = Anzahl + 1
    AnzahlBytes = AnzahlBytes + FS.GetFile(NameDatei).Size \ 1024
    FS.DeleteFile NameDatei, True
End Sub 

Skript speichern

  1. Der oben angegebene Code wird in eine normale Textdatei kopiert und als einfacher Text (*.TXT) abgespeichert, beispielsweise als „DoppelteBilderLöschen.txt

  2. Die Endung der Textdatei wird von TXT in VBS geändert: „DoppelteBilderLöschen.vbs“. Jetzt erkennt Windows die Datei als Skript.

  3. Die Datei wird am Besten im Verzeichnis C:\Dokumente und Einstellungen\[Benutzername]\SendTo\ gespeichert.

Konfiguration des Skriptes

Das Skript ist so konfiguriert, dass es RAW-Dateien von Canon (CRW und CR2) und Nikon (NEF) erkennt und gleichnamige Dateien mit der Endung JPG, JPEG oder TIFF löscht. Alle anderen Dateitypen werden von diesem Skript vollständig ignoriert.

Um das Skript an andere Dateitypen anzupassen, stehen am Anfang zwei Arrays, welche die Namen von Dateiendungen enthalten:

An Stelle der Punkte in array(....) stehen die Dateiendungen, zu denen auch der Punkt gehört. Hier kann der Anwender entweder nicht benötigte Formate entfernen oder weitere hinzufügen. Die Änderungen selbst lassen sich in jedem Texteditor ausführen. Wer dazu Textverarbeitungsprogramme wie OpenOffice Writer oder Microsoft Word nutzt, sollte diese wieder im reinen Textformat speichern, auch wenn die Programme gerne mit großem Übel drohen, weil dabei die Formatierungen verloren gehen.

Anwendung

Die Anwendung ist denkbar einfach:

  1. Im Verzeichnisbaum oder in der Dateiliste des Windows-Explorers das oder die Verzeichnisse mit den Bilddateien anwählen.

  2. Rechte Maustaste → Senden an → DoppelteBilderLöschen.vbs

  3. Das Skript fragt nun, ob eine Einzelbestätigung gewünscht wird. Dabei wird jede Löschung zur Bestätigung angezeigt. Andernfalls werden alle überflüssigen Dateien in einem Durchgang automatisch entfernt.

  4. Das Skript durchsucht das Verzeichnis und alle enthaltenen Unterverzeichnisse nach RAW-Dateien. Wenn die Dateinamen vor der Endung gleich sind aber sowohl als RAW-Format wie auch als bearbeiteter Dateityp vorliegt, wird der Bilddateityp gelöscht.

  5. Am Ende zeigt das Skript einen Dialog, bei dem die Anzahl der gelöschten Dateien und die Anzahl der freigemachten Bytes angezeigt werden.

Wichtig !!!