Fügen Sie dem Image über die Linux-Befehlszeile einen Zeitstempel hinzu


9

Ich habe einen Ordner voller Bilder. Ich versuche, dem Bild selbst für jedes Bild einen Zeitstempel hinzuzufügen, basierend auf dem Erstellungsdatum der Datei. Ist das möglich? Ich habe diesen Beitrag hier gelesen , aber er verwendet Exif-Daten. Meine Bilder haben keine Exif-Daten.

Kann ich anhand des Erstellungsdatums direkt einen Zeitstempel hinzufügen? Oder muss ich exif-Daten verwenden? Wenn ich Exif-Daten verwenden muss, wie würde ich sie mit dem Erstellungsdatum schreiben?

Ich verwende Ubuntu Server ohne GUI, daher benötige ich eine Befehlszeilenlösung. Kann jemand helfen? Vielen Dank!

Antworten:


18

Wenn Sie das Erstellungsdatum der Bilddatei in das Bild selbst schreiben möchten (wenn dies nicht gewünscht ist, bearbeiten Sie bitte Ihre Frage), können Sie verwenden imagemagick.

  1. Installieren Sie ImageMagick, falls noch nicht installiert:

    sudo apt-get install imagemagick
    
  2. Führen Sie eine Bash-Schleife aus, die das Erstellungsdatum jedes Fotos abruft, und verwenden Sie es convertaus der imagemagickSuite, um das Bild zu bearbeiten:

    for img in *jpg; do convert "$img" -gravity SouthEast -pointsize 22 \
       -fill white -annotate +30+30  %[exif:DateTimeOriginal] "time_""$img"; 
    done
    

    Dadurch wird für jedes benannte Bild foo.jpgeine Kopie time_foo.jpgmit dem Zeitstempel unten rechts erstellt. Sie können dies eleganter tun, für mehrere Dateitypen und schöne Ausgabenamen, aber die Syntax ist etwas komplexer:

OK, das war die einfache Version. Ich habe ein Skript geschrieben, das sich mit komplexeren Situationen, Dateien in Unterverzeichnissen, seltsamen Dateinamen usw. befassen kann. Soweit ich weiß, können nur PNG- und TIF-Bilder EXIF-Daten enthalten, sodass es keinen Sinn macht, dies in anderen Formaten auszuführen . Als mögliche Problemumgehung können Sie jedoch das Erstellungsdatum der Datei anstelle der EIF-Daten verwenden. Dies ist sehr wahrscheinlich nicht dasselbe wie das Datum, an dem das Bild aufgenommen wurde, sodass im entsprechenden Skript der entsprechende Abschnitt auskommentiert ist. Entfernen Sie die Kommentare, wenn Sie möchten, dass sie auf diese Weise verarbeitet werden.

Speichern Sie dieses Skript unter add_watermark.shund führen Sie es in dem Verzeichnis aus, das Ihre Dateien enthält:

bash /path/to/add_watermark.sh

Es verwendet, exiv2die Sie möglicherweise installieren müssen ( sudo apt-get install exiv2). Das Skript:

#!/usr/bin/env bash

## This command will find all image files, if you are using other
## extensions, you can add them: -o "*.foo"
find . -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.tif" -o \
 -iname "*.tiff" -o -iname "*.png" | 

## Go through the results, saving each as $img
while IFS= read -r img; do
    ## Find will return full paths, so an image in the current
    ## directory will be ./foo.jpg and the first dot screws up 
    ## bash's pattern matching. Use basename and dirname to extract
    ## the needed information.
    name=$(basename "$img")
    path=$(dirname "$img")
    ext="${name/#*./}"; 

    ## Check whether this file has exif data
    if exiv2 "$img" 2>&1 | grep timestamp >/dev/null 
    ## If it does, read it and add the water mark   
    then
    echo "Processing $img...";
    convert "$img" -gravity SouthEast  -pointsize 22 -fill white \
             -annotate +30+30  %[exif:DateTimeOriginal] \
             "$path"/"${name/%.*/.time.$ext}";
    ## If the image has no exif data, use the creation date of the
    ## file. CAREFUL: this is the date on which this particular file
    ## was created and it will often not be the same as the date the 
    ## photo was taken. This is probably not the desired behaviour so
    ## I have commented it out. To activate, just remove the # from
    ## the beginning of each line.

    # else
    #   date=$(stat "$img" | grep Modify | cut -d ' ' -f 2,3 | cut -d ':' -f1,2)
    #   convert "$img" -gravity SouthEast  -pointsize 22 -fill white \
    #          -annotate +30+30  "$date" \
    #          "$path"/"${name/%.*/.time.$ext}";
    fi 
done

Genau das suche ich! Ich erhalte jedoch die folgende Ausgabe: convert.im6: unknown image property "%[exif:DateTimeOriginal]" @ warning/property.c/InterpretImageProperties/3245. convert.im6: unable to open image `{img/%.*/.time.jpg}': No such file or directory @ error/blob.c/OpenBlob/2638.Außerdem habe ich mich noch nicht entschieden, ob ich Unterverzeichnisse verwenden möchte. Könntest du auch zeigen, wie man es benutzt find? Vielen Dank!
Andrew

@ Andrew gibt es zwei mögliche Probleme, eines ist, dass ich die Variablen nicht richtig zitiert habe und daher Leerzeichen in den Dateinamen Probleme verursachen würden. Probieren Sie das Skript in der aktualisierten Antwort aus. Wenn es immer noch fehlschlägt, enthalten Ihre Bilder wahrscheinlich nicht die erforderlichen EXIF-Daten. Ich habe dafür eine (schlechte) Problemumgehung eingefügt.
Terdon

Es ist eine Weile her, aber können Sie erklären, was "$path"/"${name/%.*/.time.$ext}"tut? Insbesondere der /%.*/Teil. Wenn ich den Teil "Zeit" in den Vordergrund stellen wollte, z. B. time.a.jpg anstelle von a.time.jpg, wie könnte ich das tun?
Andrew

@ Andrew, das ist nur String-Ersatz, siehe hier . Es wird alles nach dem letzten .Zeichen durch ersetzt .time.$ext( $extist die Erweiterung, die zuvor erfasst wurde). Um es zu schaffen time.a.jpg, ändern Sie das in ${name/#/time.}.
Terdon

-pointsize 48 oder -pointsize 72 ist sicherlich besser lesbar. :-)
Corey S.


0

Plotten Sie einfach Dateien in ein leeres Verzeichnis und leiten Sie AWK an die Shell weiter. Vielleicht ein bisschen oldskool, aber viel weniger Fancypants, viel weniger Zeichen zum Tippen, zB:

ls | awk '{print "convert "$0" -gravity SouthEast -pointsize 22 -fill white -annotate +30+30 %[exif:DateTimeOriginal] dated"$0}' | sh
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.