从Linux命令行向图像添加时间戳


9

我有一个装满图像的文件夹。我正在尝试根据文件创建的日期为每个图像添加时间戳。这可能吗?我在这里阅读了这篇文章,但是它使用了exif数据。我的图像没有exif数据。

我可以使用创建的日期直接添加时间戳吗?还是我必须使用exif数据?如果必须使用exif数据,如何使用创建的日期将其写入?

我正在使用没有GUI的Ubuntu Server,因此我需要一个命令行解决方案。有人可以帮忙吗?谢谢!

Answers:


18

如果您想将图像文件的创建日期写入图像本身(如果不是您想要的,请编辑问题),可以使用imagemagick

  1. 如果尚未安装,请安装ImageMagick:

    sudo apt-get install imagemagick
    
  2. 运行bash循环,该循环将获取每张照片的创建日期,并convertimagemagick套件中使用它来编辑图像:

    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的右下角带有时间戳。对于多种文件类型和漂亮的输出名称,您可以更优雅地执行此操作,但是语法稍微复杂一些:

好的,那是简单的版本。我编写了一个脚本,可以处理更复杂的情况,子目录中的文件,怪异的文件名等。据我所知,只有.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)

@Andrew有两个可能的问题,一个是我没有正确引用变量,因此文件名中的空格会引起问题。试试更新后的答案中的脚本。如果仍然失败,则您的图像可能不包含必要的EXIF数据,我为此提供了一种(不良)解决方法。
terdon

已经有一段时间了,但是您能解释一下"$path"/"${name/%.*/.time.$ext}"吗?特别是/%.*/部分。另外,如果我想将“时间”部分放在前面,例如time.a.jpg而不是a.time.jpg,该怎么办?
安德鲁

@Andrew只是字符串替换,请参见此处。它将..time.$ext$ext是前面捕获的扩展名)替换最后一个字符之后的所有内容。要使其变为time.a.jpg,请将其更改为${name/#/time.}
2013年

-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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.