Linuxコマンドラインからイメージにタイムスタンプを追加します


8

画像でいっぱいのフォルダーがあります。ファイルが作成された日付に基づいて、すべての画像について、画像自体にタイムスタンプを追加しようとしています。これは可能ですか?ここでこの記事を読みましたが、exifデータを使用しています。私の画像にはexifデータがありません。

作成日を使用してタイムスタンプを直接追加できますか?または、exifデータを使用する必要がありますか?exifデータを使用する必要がある場合、作成日を使用してどのように書き込むのですか?

GUIなしでUbuntu Serverを使用しているため、コマンドラインソリューションが必要です。誰でも助けることができますか?ありがとう!

回答:


17

画像ファイルの作成日付を画像自体に書き込みたい場合(それが希望するものでない場合は、質問を編集してください)、を使用できますimagemagick

  1. ImageMagickがまだインストールされていない場合はインストールします。

    sudo apt-get install imagemagick
    
  2. 各写真の作成日を取得convertし、imagemagickスイートから使用して画像を編集するbashループを実行します。

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

    という名前の各画像についてfoo.jpg、これはtime_foo.jpg、右下のタイムスタンプで呼び出されるコピーを作成します。複数のファイルタイプと適切な出力名に対してこれをよりエレガントに行うことができますが、構文はもう少し複雑です。

OK、それはシンプルなバージョンでした。より複雑な状況、サブディレクトリ内のファイル、奇妙なファイル名などに対処できるスクリプトを書きました。私が知る限り、.pngおよび.tifイメージのみがEXIFデータを含むことができるため、他の形式でこれを実行する意味はありません。 。ただし、考えられる回避策として、EIFデータの代わりにファイルの作成日を使用できます。ただし、これは画像が撮影された日付と同じではない可能性が高いため、以下のスクリプトには関連するセクションがコメントアウトされています。この方法で処理する場合は、コメントを削除してください。

このスクリプトを名前を付けて保存しadd_watermark.sh、ファイルを含むディレクトリで実行します。

bash /path/to/add_watermark.sh

exiv2インストールに必要なものを使用します(sudo apt-get install exiv2)。スクリプト:

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

これはまさに私が探しているものです!ただし、次の出力が得られます。 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.また、サブディレクトリを使用するかどうかはまだ決めていません。使い方も教えていただけますfindか?ありがとう!
アンドリュー

@Andrewには2つの問題があります。1つは変数を適切に引用していなかったため、ファイル名にスペースが含まれていると問題が発生することです。更新された回答のスクリプトを試してください。それでも失敗する場合は、おそらく画像に必要なEXIFデータが含まれていない可能性があるため、そのための(悪い)回避策を含めました。
テルドン

しばらく経ちましたが、何を説明できます"$path"/"${name/%.*/.time.$ext}"か?特に、/%.*/部品。また、a.time.jpgではなくtime.a.jpgなどの「時間」部分を前に置きたい場合、どうすればよいですか?
アンドリュー

@Andrewは単なる文字列の置換ですこちらを参照してください。最後の.文字の後のすべてを.time.$ext$ext以前にキャプチャした拡張子です)に置き換えます。にするには、それをtime.a.jpgに変更し${name/#/time.}ます。
テルドン

-pointsize 48または-pointsize 72は確かに読みやすいです。:-)
Corey S.


0

空のディレクトリにファイルをプロットし、AWKをシェルにパイプするだけです。少し古めかしいかもしれませんが、派手なパンツははるかに少なく、入力する文字もはるかに少ないです。たとえば:

ls | awk '{print "convert "$0" -gravity SouthEast -pointsize 22 -fill white -annotate +30+30 %[exif:DateTimeOriginal] dated"$0}' | sh
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.