# INSTRUCTIONS # Requires ImageMagick 7+ (to confirm your version, type magick -version into terminal, or convert -version for older versions). # Requires Exiftool (mine works with Exiftool 11.88. To confirm your version, type exiftool -ver into terminal. If metadata is not important to you, delete the exiftool commands and it will no longer be required). # Operating System: Tested on Linux Mint 20.3 (Ubuntu 20.04). Should work on most Linux OS. # Purpose: Downsize your image incrementally (aka stair stepping), relative to its width, to improve sharpness of exported image without the need for post-resize sharpening. Output is jpg. # Ideal input is 16 bit tiff with an embedded linear colour space (eg. linear rec 2020, linear sRGB, etc...). To confirm the colour space embedded in your image, open terminal, run identify -verbose /path/'image name.tif' and find the category icc:description # In file browser, rename this file Magick-Stair-Step-Resize-Width.sh, right click > properties > permissions, tick box 'is executionable', ok. # To edit: right click > open with text editor # To run: Open terminal and enter /path/Magick-Stair-Step-Resize-Width.sh # VARIABLES #For all the below, 1 refers to the first formula, and 2 for the second. # INFILE: Replace $0 with /path/'your image name.tif' # OUTFILE: Replace $1 and $2 with /path/'your image name.jpg' (Ensure OUTFILE1 and OUTFILE2 have different file names, so 2 does not overwrite 1) # STEPS: An integer. The number of increments used to downsize. More increments will lead to greater sharpness, but possibly more obvious halos, depending on the algorithm. There is likely little benefit in using more than 10. The number of -resize lines should equal the number of steps, so add (using copy/paste) or remove lines accordingly. # proportion=1/STEPS1 [eg. 1/10=0.1 will downsize towards outpx 10% at a time. eg. 1/4=0.25 will downsize towards outpx 25% at a time] # ICCPROFILE: Replace $3 with /path/'profile.icc' # outpx: Width in pixels of your desired output # -quiet: Suppresses all warning messages. Helpful if your tif has tags that libTIFF (used by ImageMagick) doesn't recognise. Remove if unnecessary. # -filter: Sinc is sharpest, but can produce halos, thus is only suitable for few steps. Lanczos is next sharpest, with much subtler halos, thus suitable for more steps. LanczosRadius is similar. # -define filter: The current settings are experimental, and help to reduce halos produced by Sinc. For a comprehensive look at filters, please visit: https://www.imagemagick.org/Usage/filter/ # -intent: Determines how out of gamut colours are mapped back in when converting from a larger colour space to a smaller one. Perceptual will shift hue slightly to retain smooth gradients (best for detail). Relative will maintain hue at the risk of unsmooth gradients, aka posterisation (best for hue accuracy). # -black-point-compensation: Ensures your darkest shadows do not get crushed to black during colour space conversion. Remove if undesired. # -profile: converts your colour space to that chosen. sRGB is standard for web display. A large selection of profiles are available here: https://github.com/ellelstone/elles_icc_profiles/tree/master/profiles (From that list, sRGB-elle-V2-srgbtrc.icc is the standard for web display. Note that they are matrix profiles, thus do not support Perceptual intent) # -quality: Applies to both jpeg and mpeg ouput formats. Accepts values from 1-100, where smaller values increase compression, thus reducing both file size and quality. When quality is >90 the chroma channels are not downsampled, making this optimal. # exiftool -TagsFromFile copies metadata from INFILE, while "all>exif:all" pastes only exif metadata to OUTFILE, preventing your xmp metadata from being overwritten. If you wish to paste all metadata, replace it with "-all>all". -overwrite_original prevents a duplicate from being created. If you don't wish to copy/paste any metadata, put a # in front of the line. (Reason to include this line is that ImageMagick cannot read/write all tiff metadata, so we use Exiftool to recover that which ImageMagick doesn't handle) # rm will delete the file listed, which is INFILE by default. If you do not wish for this to be deleted, put a # in front of the line. # The below will ouput two images using different methods. If you prefer one method, delete the other for performance gains. # The above are suggested variables. For a complete list, please visit: https://imagemagick.org/script/command-line-options.php and https://exiftool.org/ # SCRIPT INFILE=$0 OUTFILE1=$1 STEPS1=10 OUTFILE2=$2 STEPS2=2 ICCPROFILE=$3 outpx=1600 echo INFILE="${INFILE}" OUTFILE1="${OUTFILE1}" OUTFILE2="${OUTFILE2}" ICCPROFILE="${ICCPROFILE}" STEPS1=${STEPS1} STEPS2=${STEPS2} inpx=$(magick -quiet "${INFILE}" -format %w info:) proportion1=1/${STEPS1} proportion2=1/${STEPS2} echo inpx=${inpx} outpx=${outpx} proportion1=${proportion1} proportion2=${proportion2} # 1st FORMULA: 10 STEP LANCZOS magick -quiet "${INFILE}" \ -filter Lanczos \ -resize "%[fx:w-(${inpx}-${outpx})*${proportion1}]" \ -resize "%[fx:w-(${inpx}-${outpx})*${proportion1}]" \ -resize "%[fx:w-(${inpx}-${outpx})*${proportion1}]" \ -resize "%[fx:w-(${inpx}-${outpx})*${proportion1}]" \ -resize "%[fx:w-(${inpx}-${outpx})*${proportion1}]" \ -resize "%[fx:w-(${inpx}-${outpx})*${proportion1}]" \ -resize "%[fx:w-(${inpx}-${outpx})*${proportion1}]" \ -resize "%[fx:w-(${inpx}-${outpx})*${proportion1}]" \ -resize "%[fx:w-(${inpx}-${outpx})*${proportion1}]" \ -resize ${outpx} \ -intent Relative -black-point-compensation -profile "${ICCPROFILE}" \ -quality 92 \ "${OUTFILE1}" exiftool -overwrite_original -TagsFromFile "${INFILE}" "-all>exif:all" "${OUTFILE1}" # 2nd FORMULA: 2 STEP SINC magick -quiet "${INFILE}" \ -filter Sinc \ -define filter:widow=Lanczos -define filter:lobes=4 \ -resize "%[fx:w-(${inpx}-${outpx})*${proportion2}]" \ -resize ${outpx} \ -intent Relative -black-point-compensation -profile "${ICCPROFILE}" \ -quality 92 \ "${OUTFILE2}" exiftool -overwrite_original -TagsFromFile "${INFILE}" "-all>exif:all" "${OUTFILE2}" # DELETE INFILE rm "${INFILE}"