Dodaj znacznik czasu do obrazu z wiersza poleceń systemu Linux


9

Mam folder pełen zdjęć. Próbuję dodać znacznik czasu do samego obrazu, dla każdego obrazu, na podstawie daty utworzenia pliku. czy to możliwe? Przeczytałem ten post tutaj , ale używa on danych exif. Moje obrazy nie mają danych exif.

Czy mogę bezpośrednio dodać znacznik czasu, korzystając z utworzonej daty? Czy też muszę korzystać z danych exif? Gdybym musiał użyć danych exif, jak zapisałbym je przy użyciu daty utworzenia?

Używam Ubuntu Server bez GUI, więc potrzebuję rozwiązania z linii poleceń. Czy ktoś może pomóc? Dzięki!

Odpowiedzi:


18

Jeśli chcesz zapisać datę utworzenia pliku obrazu w samym obrazie (jeśli nie tego chcesz, edytuj swoje pytanie), możesz użyć imagemagick.

  1. Zainstaluj ImageMagick, jeśli jeszcze nie został zainstalowany:

    sudo apt-get install imagemagick
    
  2. Uruchom pętlę bash, która pobierze datę utworzenia każdego zdjęcia i użyj convertz imagemagickpakietu do edycji obrazu:

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

    Dla każdego nazwanego obrazu foo.jpgzostanie utworzona kopia o nazwie time_foo.jpgze znacznikiem czasu w prawym dolnym rogu. Możesz to zrobić bardziej elegancko, dla wielu typów plików i ładnych nazw wyjściowych, ale składnia jest nieco bardziej złożona:

OK, to była prosta wersja. Napisałem skrypt, który może poradzić sobie z bardziej złożonymi sytuacjami, plikami w podkatalogach, dziwnymi nazwami plików itp. O ile mi wiadomo, tylko obrazy .png i .tif mogą zawierać dane EXIF, więc nie ma sensu uruchamiać tego w innych formatach . Jednak jako możliwe obejście można użyć daty utworzenia pliku zamiast danych EIF. Prawdopodobnie nie jest to ta sama data, co data zrobienia zdjęcia, więc poniższy skrypt zawiera komentarz do odpowiedniej sekcji. Usuń komentarze, jeśli chcesz je przetwarzać w ten sposób.

Zapisz ten skrypt jako add_watermark.shi uruchom go w katalogu zawierającym pliki:

bash /path/to/add_watermark.sh

Wykorzystuje to, exiv2co może wymagać instalacji ( sudo apt-get install exiv2). Scenariusz:

#!/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

Właśnie tego szukam! Otrzymuję jednak następujące dane wyjściowe: 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.Nie zdecydowałem też, czy chcę jeszcze używać podkatalogów; czy możesz również pokazać, jak używać find? Dzięki!
Andrew

@Andrew istnieją dwa możliwe problemy, jednym z nich jest to, że nie cytowałem poprawnie zmiennych, więc spacje w nazwach plików mogą powodować problemy. Wypróbuj skrypt w zaktualizowanej odpowiedzi. Jeśli nadal nie powiedzie się, twoje zdjęcia prawdopodobnie nie zawierają niezbędnych danych EXIF, załączyłem (złe) obejście tego problemu.
terdon

Minęło trochę czasu, ale czy możesz wyjaśnić, co "$path"/"${name/%.*/.time.$ext}"robi? W szczególności /%.*/część. Ponadto, jeśli chciałbym umieścić na początku część „czas”, np. Time.a.jpg zamiast a.time.jpg, jak mogę to zrobić?
Andrew,

@Andrew, który zastępuje ciąg znaków, zobacz tutaj . Zastąpi wszystko po ostatnim .znaku .time.$ext( $extjest to przechwycone wcześniej rozszerzenie). Aby to zrobić time.a.jpg, zmień to na ${name/#/time.}.
terdon

-pointsize 48 lub -pointsize 72 jest z pewnością bardziej czytelny. :-)
Corey S.,


0

Po prostu wykreśl pliki do pustego katalogu i potokuj AWK do powłoki. Może trochę oldskool, ale o wiele mniej fantazyjnych, o wiele mniej znaków do pisania, np .:

ls | awk '{print "convert "$0" -gravity SouthEast -pointsize 22 -fill white -annotate +30+30 %[exif:DateTimeOriginal] dated"$0}' | sh
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.