#!/bin/bash # # Modified by Paul Sherman for Absolute Linux # latest edit: 05/14/2020 # Name: exifedit # Depends: perl_exiftool, yad # Purpose: Read and write meta information in pictures # # Original by: # (c) K.J. Jeitler (kjoe) 2013 # called "ExZenToo" # # LICENSE: GPL-2 # This package is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation version 2 of the License. # # This script is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You can get a copy of the GNU General Public License # at ######################## # CHECK FOR DEPENDENCIES: ######################################################################################## ######################## if [[ "$DISPLAY" && "$(which Xdialog 2>&1 | grep -v "which: no")" ]]; then dialog="Xdialog" else dialog="dialog" fi # Check whether Yad is installed. If it's not installed, open a terminal and inform the user about unmet dependencies. In addition (experimental) try to find a terminal emulator and provide the same information. if ! [ -x "$(command -v yad)" ]; then echo 'Error: yad is not installed.' >&2 $dialog --title "Yad not found..." --msgbox "Yad needs to be installed to run this program.\n" 0 0 exit 1 fi if ! [ -x "$(command -v exiftool)" ]; then echo 'Error: exiftool is not installed.' >&2 $dialog --title "exiftool not found..." --msgbox "exiftool needs to be installed to run this program.\n" 0 0 exit 1 fi echo 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFuklEQVRYw7WXaWxUVRTHf/fNdGY6 TItQwGqRRQk0ZVGUVlE2TRVwLSQVURBTjUKIEKGKCwbkAwZRDBVFEENwqaSKRXANKLJIWYIsYqGW 4CB0Wgdooe0w25t3/DCltsyUeXW5k5fJO+c/9/zv2e4ZlZOTI2fOnOH/WCNGjGD16tXqchir2+3G lZJKn4GD4wIMAYkjlzbkF/GH9+zAXVWTkKTVMAwGjxrN0NnLYpT+hnP468/ROaNXu09/euo96CIJ cRpAxGgtrD95iMCW0dzo7UOeIwvHzkF4965qNwkxgbGKCHoLZPBCA+meAqZN2dcsyx78C7/8NotP fu1CWv+8f0RAKZWfl5dXopSitLR0koh83Ewg0gJ59udVPP/QvpjNBvZtYNOhNQjmCKT16MPVyXLR +FSl1PL169dfVH+klLpORBZol3rAqarRtPibOrUa06fPe3EpJSOLhiqlHgbeuSvdjmc4eIbDmK4W lFKvKKWGR0PQIgf8Sf1paFSkuGIjeDZ4LY525ECRc0tZoc1GTt8efNHtGPamg5UMiHD9Pju9brp1 m3ZpCNKHTGZx8V3oeuvNPt90DaGeL5g2/mflYV6acjehUIiKU25qQn/rUiww+UqD3bt3x+aA0jSc o0qZ+9Hz9HDtwWbxUd3Yl3DvuXTsPsCU8frT1Xz45G2EgwGm3w9vb9DJq3TwU1YApyWK6WBPIhAI RAmI0boOkxzJdL1jKX7ADzjb4fZw4AIl027B661nzXMwfhg4HbC4JMAjBqwbBJqCjeoaMjMtWAUQ kf+k9Yph8HXhKI6W/8GrBVHjAPMmgbtG8ek2YVYlDMgeyo7NZQAzoh4QI+6GET3M4c2leH+vICXt Sq4fk09yaqc2Cex54xG2/7CXaffBjHEtewAsnykcO+Vi6fFGtFO7mTBhAmvXrn1LOTt0kIFjJ5K/ 4L3WSXT8CMWFD1N19ECzLLXrVTy2bD09BuYAUFvlpmztcuo8J0gOeCjbsp17b4biF8ESp5R/dndh +NNnyMrKory8PEVEGps80DoER7Z+RXHhRAL+RqxjLBg3RZBK8H1xmpUFuUx5q5Tak8fZ8Npsgr6G vztmP1j9bHzjYR3mvK9ISUmhvLw8S0QamzthyyTctuZNvnz9WZRLQaFgZEaibrwOJFMnuMTHioLc aLKm21G3g3wJ3dLhs5fBaY8fnjmrYOeB0wAPisiR5stIDMHQwxgRnXXzp7Jh0SxUhkLm6qjMS3bp BWq2AcnRVz03iNoFLhd8Nw+6dIxv/OPvYcVXkGSlSEQ+balTNrtdMvpnY7U7qCzbjD27A+ECH9gv k+1HQZYAOlgtsHEBjBgUH7v/GOTOgSE3DmLHrkM2EQm3IpBks0k4FG1TnR/I4Nz9VaAS1JsO2nyF 7hHenQmTc+PDztbDsGcUIa6gxlt3tYhUx1zHiGCxWOk7PZuKG8pM1fsVnydT6/FTmN+2cT0Cj76m 8NRq6HrdqHjGozkgQs64HNPGrz2YTu23fsYPg/mT28bN+wB+PCjoemS2iGy97ETk54Ip45aQhZPL a8jpByufiTaYeGvdDlhaCuoqdorIkoQzoU/3mSIQCUcIh+CJsZBsi4/57RRMXZaE6q7DLClOOBOK CD69sV09v62Tn/fBuIWp+NFhuqA6EjQ1lJr1wOWWIfD42xmcqGqApwS6mftdkwdMEmi6y8NaUoxq 0cZ+fLO9CjUe1ACQYhi55Y73Ek7F0bE8krD0WxI4Kt05H6xrFm891puF7x8k7dbO1I2tjQq94A15 MUXA9LJGn6Ilv1PUKrf3k9Eng+pJJprYvyKgQOUDHiAIRCDZ4qSnqyfn7qnl0onVleT6jwkA6s7W 7wEuUMGR2P8F9jQ62TqZIyAVwJr2EbFb7NFHs2Nr+m4pc3vcSFriUc/qSHUQPh9G26dQSkOhUErR /FEKjVhd86CBThgdH7GV5HIlDsFfeDNlrT35U9oAAAAASUVORK5CYII=' | base64 -d > /tmp/icon.png ######################### # DEFINE VARIABLES: ############################################################################################# ######################### SEPARATOR="______________________________________________________________________________________________" SEPARATOR2="___________________________________________________________________________" #################### # SUBROUTINES: ################################################################################################## #################### # welcome dialog and disclaimer welcome() { ANSWER="" ANSWER=$(yad --list --center --window-icon="/tmp/icon.png" --title "Welcome to exifedit" --text "exifedit is a Linux application for reading, writing and modifying EXIF data \nand other meta information in image files.\n\nIn fact it's a bash script using yad as a graphical user interface (GUI) for the \npowerful command-line application ExifTool by Phil Harvey.\n\nHow to use the program:\nAt first choose an image. This is the first step to either edit just this single file \nor several files located within the same directory.\n$SEPARATOR2\n\nThis script is published in the hope that it will be useful to you. It is explicitly \nrecommended that you make back-up copies of your image data files before \nyou start using this script. The script is provided under a GPL license.\nThe author does not assume any liability for any damage caused directly or \nindirectly out of or in connection with the usage of this script.\nFurthermore, the author does not provide any guarantee and/or warranty as \nfor the proper operation of the script. You are using this script at your own risk \nand responsbility. By using this script you agree to the terms and conditions of \nthe license agreement." --checklist --column "" --column "" FALSE "Do not show this dialog again." --height=485 --cancel-label="I do not agree. Exit program now." --ok-label="Ok") if [ $? != 0 ]; then exit; fi if [ -n "$ANSWER" ]; then touch ~/.exifedit/.exifedit; fi return; } # File selection dialog ............................................................................................. # input: none; output: DIR_FILE, DIR, FILE, EXT file_choose() { TITLE="Please select an image"; DIR_FILE=$(yad --file-selection --window-icon="/tmp/icon.png" --file-filter='Image Files | *.jpg *.jpeg *.png *.pdf *.psd *.heic *.eps *.xmp *.cr2 *.cr3 *.crw *.tiff *.tif *.icc *.nef *.orf *.sr2 *.dng *.ai *.arw *.3fr *.fff *.mrw *raw *.rw2 *.mos *.JPG *.gif *.JPEG *.PNG *.PDF *.PSD *.HEIC *.EPS *.XMP *.CR2 *.CR3 *.CRW *.TIFF *.TIF *.ICC *.NEF *.ORF *.SR2 *.DNG *.AI *.ARW *.3FR *.FFF *.MRW *.RAW *.RW2 *.MOS *.GIF' --width=740 --height=660 --center --title="$TITLE") if [ $? != 0 ]; then exit; fi DIR=$(dirname "$DIR_FILE") FILE=$(basename "$DIR_FILE") EXT=$(echo ${FILE#*.}) return; } # Show the working directory, file names, file status and some EXIF data / meta data ........................... # then ask, if the user wants to continue with this selection # input: DIR, FILE; output: $? file_info() { FILE_STAT=$(INFO=$(stat "$DIR/$FILE" | grep "\."); echo "${INFO// /}") FILE_EXIF=$(exiftool -G -lang en -alldates -gps:all -iptc:all -ifd0:all "$DIR/$FILE" | head -n 10) TEXT="$SEPARATOR\n\nSelected directory: $DIR\nSelected file: $FILE\n$SEPARATOR\n\nFile status (according to file system):\n\n$FILE_STAT\n$SEPARATOR\n\nEXIF/Meta data (only a representative selection):\n\n$FILE_EXIF\n$SEPARATOR\n\nWould you like to proceed?" yad --question --window-icon="/tmp/icon.png" --center --title "Show selection and confirm" --text "$TEXT" --cancel-label="Exit program" --ok-label="Continue"; if [ $? != 0 ]; then exit; fi; return; } # Start main menu ............................................................................................. start_main_menu() { main_menu; } # Get selected EXIF time(s) .............................................................................. # input: TEXT, MAIN_FN; output: EXIF_T1, EXIF_T2, EXIF_T3 exif_times() { ANSWER="" ANSWER=$(yad --list --title "$MAIN_FN" --center --window-icon="/tmp/icon.png" --text "$TEXT" --checklist --column "" --column "" TRUE "date/time the image was generated (DateTimeOriginal)" TRUE "date/time the digital image data was stored (CreateDate)" TRUE "date/time the image file was changed (ModifyDate)" --width=450 --height=260 --separator="") if [ $? != 0 ]; then start_main_menu; fi; if [ ! -n "$ANSWER" ]; then no_exif_times; fi EXIF_T1="$(echo $ANSWER | grep -o DateTimeOriginal)" EXIF_T2="$(echo $ANSWER | grep -o CreateDate)" EXIF_T3="$(echo $ANSWER | grep -o ModifyDate)" return; } # Info: no EXIF time(s) selected ............................................................................ # input: MAIN_FN; output: none no_exif_times() { yad --info --title "$MAIN_FN" --center --window-icon="/tmp/icon.png" --text "You did not select any of the EXIF times!" --ok-label="Back to main menu"; start_main_menu } # Determine files to be modified: only one file, all files with the same extension, .................................. # all files in the working directory, or all files with specific information in the EXIF data / meta data # input MAIN_FN, DIR, FILE, EXT; output: ONE_ALL_X one_all_x() { ONE_ALL_X="" ANSWER="" SEL1=$(echo "only the file $FILE") SEL2=$(echo "all $EXT-files in $DIR") SEL3=$(echo "all files in $DIR") SEL4=$(echo "files with specific information in the EXIF or meta data") TEXT=$(echo "Which file(s) would you like to modify?") ANSWER=$(yad --list --title "$MAIN_FN" --center --window-icon="/tmp/icon.png" --text "$TEXT" --radiolist --column "" --column "" TRUE "$SEL1" FALSE "$SEL2" FALSE "$SEL3" FALSE "$SEL4" --width=450 --height=220 --cancel-label="Cancel" --ok-label="Continue") if [ $? != 0 ]; then start_main_menu; fi; ANSWER=`echo ${ANSWER} | cut -d'|' -f 2` case $ANSWER in "$SEL1") ONE_ALL_X="\"$DIR/$FILE\"";; "$SEL2") ONE_ALL_X="-ext .$EXT \"$DIR/\"";; "$SEL3") ONE_ALL_X=" . \"$DIR/\"";; "$SEL4") meta_info; ONE_ALL_X=$(echo "$META_INFO \"$DIR/\"");; esac return; } # Query: Which tag or group information must be contained in the file(s)? # input: MAIN_FN; output: META_INFO meta_info() { EXAMPLE1=$(echo -if \'\$make eq "Casio"\') EXAMPLE2=$(echo -if \'not \$exif:iso\') TEXT=$(echo "Here you can select files based on existing or missing EXIF/meta data for the processing step you intend to carry out. \nFor this purpose you can use information in tags and/or groups.\n\nPlease be sure you enter the correct syntax (see exiftool documentation at: \nhttp://owl.phy.queensu.ca/~phil/exiftool/exiftool__pod.html)\n\nExamples:\n\nall images with CASIO in tag make\n$EXAMPLE1\n\nimages without EXIF ISO values\n$EXAMPLE2") META_INFO=$(yad --entry --title "$MAIN_FN" --center --window-icon="/tmp/icon.png" --text "$TEXT" --entry-text "$EXAMPLE1") if [ ! -n "$META_INFO" ]; then one_all_x; fi if [ $? != 0 ]; then one_all_x; fi return; } # Determine whether the original image(s) or a copy should be edited ..... write_copy() { WRITE_COPY="" ANSWER="" SEL1=$(echo "edit a copy of the file(s)") SEL2=$(echo "overwrite original image(s) (not recommended)") TEXT="How would you like to proceed?" ANSWER=$(yad --list --title "$MAIN_FN" --center --window-icon="/tmp/icon.png" --text "$TEXT" --radiolist --column "" --column "" TRUE "$SEL1" FALSE "$SEL2" --width=450 --height=165 --cancel-label="Back" --ok-label="OK") if [ $? != 0 ]; then start_main_menu; fi; ANSWER=`echo ${ANSWER} | cut -d'|' -f 2` case $ANSWER in "$SEL1") WRITE_COPY="";; "$SEL2") WRITE_COPY="-overwrite_original";; esac return; } # Provide information on the command that will be executed and confirm # input: TEXT, output: none exec_info() { yad --question --title "exitedit - Information" --center --window-icon="/tmp/icon.png" --no-markup --text "$TEXT" --cancel-label="Cancel" --ok-label="Execute, then return to main menu" if [ $? != 0 ]; then start_main_menu; fi; bash -c "$EXEC" return; } # Which meta data should be modified? # input: MAIN_FN, TEXT; output: THIS_META this_meta() { ANSWER="" SEL1=$(echo "all EXIF and meta data in the file") SEL2=$(echo "EXIF times (all or selected ones)") SEL3=$(echo "all EXIF GPS data") SEL4=$(echo "all IPTC data") SEL5=$(echo "please enter tag/group") ANSWER=$(yad --list --title "$MAIN_FN" --center --window-icon="/tmp/icon.png" --text "$TEXT" --radiolist --column "" --column "" TRUE "$SEL1" FALSE "$SEL2" FALSE "$SEL3" FALSE "$SEL4" FALSE "$SEL5" --width=450 --height=290 --cancel-label="Cancel" --ok-label="Continue") if [ $? != 0 ]; then start_main_menu; fi; ANSWER=`echo ${ANSWER} | cut -d'|' -f 2` case $ANSWER in "$SEL1") THIS_META="-all=";; "$SEL2") TEXT="Which EXIF time(s) would you like to delete?" exif_times; SHIFT1=""; if [ -n "$EXIF_T1" ]; then SHIFT1="-$(echo $EXIF_T1=)"; fi SHIFT2=""; if [ -n "$EXIF_T2" ]; then SHIFT2="-$(echo $EXIF_T2=)"; fi SHIFT3=""; if [ -n "$EXIF_T3" ]; then SHIFT3="-$(echo $EXIF_T3=)"; fi if [ ! -n "$(echo $SHIFT1$SHIFT2$SHIFT3)" ]; then no_exif_times; fi THIS_META="$SHIFT1 $SHIFT2 $SHIFT3";; "$SEL3") THIS_META="-gps:all=";; "$SEL4") THIS_META="-iptc:all=";; "$SEL5") this_tag_group; if [ ! -n "$THIS_TAG_GROUP" ]; then start_main_menu; fi if [ $? != 0 ]; then start_main_menu; fi THIS_META="$THIS_TAG_GROUP=";; esac return; } # Which tag or tag groups should be modified? # input: MAIN_FN, TEXT; output: THIS_TAG_GROUP this_tag_group() { EXAMPLE1=$(echo -comment) EXAMPLE2=$(echo -ThumbnailImage) EXAMPLE3=$(echo -MakerNotes:all) EXAMPLE4=$(echo -Orientation) TEXT=$(echo "Here you can select the EXIF and/or meta data for the processing step you intend to carry out. \nFor this purpose you can use information in tags and/or groups.\n\nPlease be sure you enter the correct syntax (see exiftool documentation at: \nhttp://owl.phy.queensu.ca/~phil/exiftool/exiftool__pod.html)\n\nExamples: \n\n$EXAMPLE1\n$EXAMPLE2\n$EXAMPLE3\n$EXAMPLE4\n") THIS_TAG_GROUP=$(yad --entry --title "$MAIN_FN" --center --window-icon="/tmp/icon.png" --text "$TEXT" --entry-text "$EXAMPLE1") return; } # Select source file whose meta data should be copied # input: none; output: SOURCE_FILE source_file() { TITLE="Please select another image containing meta data to be copied!"; SOURCE_FILE=$(yad --file-selection --center --window-icon="/tmp/icon.png" --title="$TITLE") if [ $? != 0 ]; then exit; fi return; } # Use file modification date (mtime) as EXIF time(s) # input: DIR, FILE; output: none mtime_exif() { FILE_MOD_DATE=$(exiftool -b -FileModifyDate "$DIR/$FILE") TEXT=$(echo "Here you can use the modification time of a file as provided by the operating system (mtime) as EXIF time(s)."; echo "e. g., for $FILE this would be: $FILE_MOD_DATE."; echo ""; echo "Into which EXIF time field(s) should the file modification time(s) be copied?") exif_times PART1=""; if [ -n "$EXIF_T1" ]; then PART1="'-$(echo $EXIF_T1\