2012年9月1日 星期六

用 exiftool 查看/(整批)編修圖檔裡面的文字資訊

先前美妝部落客照片時間順序不對被抓包一事, 網友是怎麼看出來的呢? 資料夾裡雜亂的一堆相片, 哪幾張是用哪部相機拍的呢? 當初拍攝時所採用的光圈/快門是多少? 有沒有用閃光燈? 如果你會操作 exiftool 查詢增刪相片裡面的 IPTC/IIF/XMP/EXIF 等等文字資訊, 就能回答上面的問題。 請搜尋 「exif 相片」 或 「exiftool 相片」 可以找到很多圖形介面的教學文。 但是 真正的男子漢是不用滑鼠的 貴哥習慣用 regexp 批次處理大量資料, 所以這帖要分享命令列版的操作方式。

在 fedora 底下, 要安裝 perl-Image-ExifTool 套件; 在 ubuntu 底下, 要安裝 libimage-exiftool-perl 套件。

如果要查看一張圖片內含的所有文字資訊:

        exiftool photo.jpg

也一以一口氣查看某個目錄下所有圖片檔內含的所有文字資訊:

        exiftool photos/

我自己的話, 因為習慣用 regexp 及 $(...) 批次處理大量的資料, 所以要把每張圖片的資料放在同一列比較方便。 例如下列指令可以印出 2012/07 2012/08 兩個子目錄底下圖片的 「拍攝日期、 寬度與高度、 檔名(含路徑名稱)」, 每張圖片的資料佔用一列:

        exiftool -p '$CreateDate $ImageSize $Directory/$FileName' 2012/07 2012/08

理論上拍照時, 相機應該立即將拍攝日期存進相片的 CreateDate 跟 DateTimeOriginal 這兩個欄位裡面。 如果你事後才要補上, 可以這麼做:

        exiftool -CreateDate='2012:12:21 11:12:00' photo.jpg
        exiftool -DateTimeOriginal='2012:12:21 11:12:00' photo.jpg

或者, 如果不介意把第三個欄位 ModifyDate 也同時一起改掉的話, 可以這樣下:

        exiftool -alldates='2012:12:21 11:12:00' photo.jpg

如果你的相片上已有一個欄位是正確的 (例如 DateTimeOriginal) 而另一個欄位是空的或錯誤的 (例如 CreateDate) 那麼可以把正確的欄位內容複製過來:

        exiftool -CreateDate'<'DateTimeOriginal photo.jpg

改完之後請查詢確認一下:

        exiftool -p '$CreateDate $DateTimeOriginal $Directory/$FileName' photo.jpg

也請見 Copy the file date to EXIF。 注意 < 兩旁的引號。 因為在 shell 底下, < 跟 > 分別代表輸入與輸出重新導向, 如果沒把它括起來, 會被 shell 誤撿去解釋; 而 exiftool 反而就看不到了。

處理標籤 (Keywords 或 Subject) 欄位時, 比 = (指定標籤) 更常用的可能是 += (新增一個標籤) 或 -= (刪除一個標籤)。 例如相片檔 elephant.jpg 如果原本有 '大象' 跟 '水' 兩個 keywords, 那麼 exiftool -Keywords+='哺乳動物' elephant.jpg 之後, 就會變成 '大象'、 '水'、 '哺乳動物' 三個 keywords。

Exiftool 可以顯示/修改很多欄位。 請用 exiftool -list 列出它認得的所有欄位。

用命令列處理相片的好處就是: 搭配 regexp 命令結果代換, 很容易就可以批次大量處理許多相片。 例如要一口氣把 photos/ 子目錄、 孫目錄... 底下所有的相片各自的 DateTimeOriginal 欄位複製到 CreateDate 欄位, 可以這樣做:

        exiftool -CreateDate'<'DateTimeOriginal $(find photos/ -type d)

貴哥之所以學用 exiftool 處理相片, 主要是為了增/刪/改標籤 (tag)。 不過這個問題有點複雜, 就等另一帖再談囉。

6 則留言:

  1. 請問一下...當我有大量JPG圖檔...想要把主旨改成跟檔名一樣...這樣要怎麼做?

    回覆刪除
    回覆
    1. 要在圖檔的 Subject 欄填入檔名 (不含副檔名) 嗎? 先下這個指令: ls *.JPG | perl -pe 's#(.*?)\.JPG# exiftool -Subject"=$1" $1.JPG#' 看一下它印出來的指令是否符合要求 (剪貼一兩句執行看看), 若 ok 的話, 再把它整個送給 bash (在後面加 | bash)。

      刪除
    2. 感謝回答^^...對我就是要Subject欄填入filename...可是我看不懂要怎弄XD

      刪除
  2. 請問一下喔,我用電腦編輯過的相片是jpeg檔,但想使用相片打印機打印時,被要求必須要使用符合exif的映像,請問有方法轉檔嗎?

    回覆刪除
    回覆
    1. 用 gimp 開啟、 再匯出, 看是否能修正錯誤。 不然就用軟體名稱跟 exif (或錯誤訊息) 下去搜尋比較精確囉。 或是分享一張錯誤照片並告知軟體名稱,我來看看是哪裡出問題。

      刪除
  3. 提供我自己的一點點小建議.
    command line 優勢在於有效率處理專一問題. 而 GUI 應用程式優勢在於直覺.

    關於 GUI 應用程式 : 除了 Gimp 也可以考慮 Krita, 我覺的 Krita 比 Gimp 直覺很多. 而且很多圖形操控是 Gimp 沒有的.
    Krita 本來是在 KDE 平台但是 Gnome 也可以裝, 我用 Debian Gnome 可以用 Krita 沒問題.

    回覆刪除