Last active
August 3, 2021 20:13
-
-
Save agates4/54be4a8584ee5e80d02f6b601e7d3e6a to your computer and use it in GitHub Desktop.
Script to turn a given image into a beautiful screenshot with rounded corners, drop shadow, and whitespace
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<array> | |
<dict> | |
<key>Activate</key> | |
<string>Normal</string> | |
<key>CreationDate</key> | |
<real>622511872.68444896</real> | |
<key>Macros</key> | |
<array> | |
<dict> | |
<key>Actions</key> | |
<array> | |
<dict> | |
<key>Conditions</key> | |
<dict> | |
<key>ConditionList</key> | |
<array> | |
<dict> | |
<key>Button</key> | |
<integer>0</integer> | |
<key>ConditionType</key> | |
<string>MouseButton</string> | |
</dict> | |
</array> | |
<key>ConditionListMatch</key> | |
<string>All</string> | |
</dict> | |
<key>MacroActionType</key> | |
<string>PauseUntil</string> | |
<key>TimeOutAbortsMacro</key> | |
<true/> | |
</dict> | |
<dict> | |
<key>Conditions</key> | |
<dict> | |
<key>ConditionList</key> | |
<array> | |
<dict> | |
<key>Button</key> | |
<integer>0</integer> | |
<key>ConditionType</key> | |
<string>MouseButton</string> | |
<key>Pressed</key> | |
<false/> | |
</dict> | |
</array> | |
<key>ConditionListMatch</key> | |
<string>All</string> | |
</dict> | |
<key>MacroActionType</key> | |
<string>PauseUntil</string> | |
<key>TimeOutAbortsMacro</key> | |
<true/> | |
</dict> | |
<dict> | |
<key>MacroActionType</key> | |
<string>Pause</string> | |
<key>Time</key> | |
<string>0.2</string> | |
<key>TimeOutAbortsMacro</key> | |
<true/> | |
</dict> | |
<dict> | |
<key>Conditions</key> | |
<dict> | |
<key>ConditionList</key> | |
<array> | |
<dict> | |
<key>ClipboardConditionType</key> | |
<string>HasImage</string> | |
<key>ClipboardText</key> | |
<string></string> | |
<key>ConditionType</key> | |
<string>Clipboard</string> | |
</dict> | |
</array> | |
<key>ConditionListMatch</key> | |
<string>All</string> | |
</dict> | |
<key>ElseActions</key> | |
<array/> | |
<key>MacroActionType</key> | |
<string>IfThenElse</string> | |
<key>ThenActions</key> | |
<array> | |
<dict> | |
<key>Append</key> | |
<false/> | |
<key>Destination</key> | |
<string>/Users/personal/Workspace/drop-shadow/temp.png</string> | |
<key>Encoding</key> | |
<string>UTF8</string> | |
<key>Format</key> | |
<string>PNG</string> | |
<key>Format2</key> | |
<string>PNG</string> | |
<key>MacroActionType</key> | |
<string>WriteFile</string> | |
<key>Source</key> | |
<string>Clipboard</string> | |
</dict> | |
<dict> | |
<key>DisplayKind</key> | |
<string>Window</string> | |
<key>HonourFailureSettings</key> | |
<true/> | |
<key>IncludeStdErr</key> | |
<true/> | |
<key>MacroActionType</key> | |
<string>ExecuteShellScript</string> | |
<key>Path</key> | |
<string>~/Workspace/drop-shadow/drop-shadow.sh</string> | |
<key>Source</key> | |
<string>Nothing</string> | |
<key>Text</key> | |
<string>./Users/personal/Workspace/drop-shadow/drop-shadow.sh /Users/personal/Workspace/drop-shadow/temp.png</string> | |
<key>TimeOutAbortsMacro</key> | |
<true/> | |
<key>TrimResults</key> | |
<true/> | |
<key>TrimResultsNew</key> | |
<true/> | |
<key>UseText</key> | |
<true/> | |
</dict> | |
</array> | |
<key>TimeOutAbortsMacro</key> | |
<true/> | |
</dict> | |
</array> | |
<key>CreationDate</key> | |
<real>622511932.61007595</real> | |
<key>ModificationDate</key> | |
<real>623533929.95638096</real> | |
<key>Name</key> | |
<string>Apply shadow to screenshot</string> | |
<key>Triggers</key> | |
<array> | |
<dict> | |
<key>FireType</key> | |
<string>Pressed</string> | |
<key>KeyCode</key> | |
<integer>21</integer> | |
<key>MacroTriggerType</key> | |
<string>HotKey</string> | |
<key>Modifiers</key> | |
<integer>768</integer> | |
</dict> | |
</array> | |
<key>UID</key> | |
<string>5EFD8E79-1CE2-4B4E-95D6-A0156AF1379F</string> | |
</dict> | |
</array> | |
<key>Name</key> | |
<string>Global Macro Group</string> | |
<key>ToggleMacroUID</key> | |
<string>837A4569-414A-45B0-B086-D85B3AAE90D0</string> | |
<key>UID</key> | |
<string>55D3F2B4-0024-4857-9E8D-02CF4B05D3D2</string> | |
</dict> | |
</array> | |
</plist> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# --------------------------------- | |
# set this script as an executable: | |
# chmod u+x drop-shadow.sh | |
# example usage: | |
# ./Users/personal/Workspace/drop-shadow/drop-shadow.sh /Users/personal/Workspace/drop-shadow/temp.png | |
# --------------------------------- | |
# we need a filename as an argument | |
if [ $# -eq 0 ]; then | |
echo "Needs the filename as the first argument" | |
exit -1 | |
fi | |
# Required package | |
type /usr/local/bin/convert >/dev/null 2>&1 || { echo >&2 "The convert command must be available (from imagemagick)."; exit 1; } | |
# use our argument path as our input filename | |
input_filename="${1}" | |
# set our output directory for temp images | |
output_dir="/Users/personal/Workspace/drop-shadow/" | |
# https://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash#965072 | |
filename=$(basename -- "${input_filename}") | |
extension="${filename##*.}" | |
filename="${filename%.*}" | |
# get the mean colorspace as a decimal | |
colorspace=$(/usr/local/bin/convert "${input_filename}" -colorspace gray -format "%[fx:100*mean]%%" info:) | |
colorspace=$(echo $colorspace|perl -pe 's{\d+\.\d+%}{$&/100}eg') | |
# chose shadow color based on colorspace of the image | |
chosen_shadow="#000" | |
[ "`echo "${colorspace} < 1.0" | bc`" -eq 1 ] && chosen_shadow="#B0B0B0" | |
[ "`echo "${colorspace} < 0.91" | bc`" -eq 1 ] && chosen_shadow="#AAA" | |
[ "`echo "${colorspace} < 0.6" | bc`" -eq 1 ] && chosen_shadow="#333" | |
[ "`echo "${colorspace} < 0.2" | bc`" -eq 1 ] && chosen_shadow="#222" | |
[ "`echo "${colorspace} < 0.1" | bc`" -eq 1 ] && chosen_shadow="#000" | |
# generate rounded corners for image | |
/usr/local/bin/convert "${input_filename}" \( +clone -alpha extract -draw 'fill black polygon 0,0 0,15 15,0 fill white circle 15,15 15,0' \( +clone -flip \) -compose Multiply -composite \( +clone -flop \) -compose Multiply -composite \) -alpha off -compose CopyOpacity -composite "${output_dir}${filename}_shadow.${extension}" | |
# generate shadow for image | |
/usr/local/bin/convert "${output_dir}${filename}_shadow.${extension}" \( +clone -background "${chosen_shadow}" -shadow 100x10+0+10 \) +swap -background none -layers merge +repage "${output_dir}${filename}_shadow.${extension}" | |
# generate whitespace for image | |
/usr/local/bin/convert "${output_dir}${filename}_shadow.${extension}" -bordercolor none -border 1 -gravity south -background none -splice 0x25 "${output_dir}${filename}_shadow.${extension}" | |
# copy generated image to clipboard | |
osascript -e "set the clipboard to (read (POSIX file \"${output_dir}${filename}_shadow.${extension}\") as JPEG picture)" |
That's cool.
That looks really nice , how do I install?
updated with dynamically generated whitespace based on image dimensions
and don't need to install copyq - using normal copy tool prepackaged with OS X
#!/usr/bin/env bash
# ---------------------------------
# set this script as an executable:
# chmod u+x drop-shadow.sh
# example usage:
# ./Users/personal/Workspace/drop-shadow/drop-shadow.sh /Users/personal/Workspace/drop-shadow/temp.png
# ---------------------------------
# we need a filename as an argument
if [ $# -eq 0 ]; then
echo "Needs the filename as the first argument"
exit -1
fi
# Required package
type /usr/local/bin/convert >/dev/null 2>&1 || { echo >&2 "The convert command must be available (from imagemagick)."; exit 1; }
# use our argument path as our input filename
input_filename="${1}"
# set our output directory for temp images
output_dir="/Users/personal/Workspace/drop-shadow/"
# https://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash#965072
filename=$(basename -- "${input_filename}")
extension="${filename##*.}"
filename="${filename%.*}"
# get the mean colorspace as a decimal
colorspace=$(/usr/local/bin/convert "${input_filename}" -colorspace gray -format "%[fx:100*mean]%%" info:)
colorspace=$(echo $colorspace|perl -pe 's{\d+\.\d+%}{$&/100}eg')
# chose shadow color based on colorspace of the image
chosen_shadow="#000"
[ "`echo "${colorspace} < 1.0" | bc`" -eq 1 ] && chosen_shadow="#B0B0B0"
[ "`echo "${colorspace} < 0.91" | bc`" -eq 1 ] && chosen_shadow="#AAA"
[ "`echo "${colorspace} < 0.6" | bc`" -eq 1 ] && chosen_shadow="#333"
[ "`echo "${colorspace} < 0.2" | bc`" -eq 1 ] && chosen_shadow="#222"
[ "`echo "${colorspace} < 0.1" | bc`" -eq 1 ] && chosen_shadow="#000"
# generate rounded corners for image
/usr/local/bin/convert "${input_filename}" \( +clone -alpha extract -draw 'fill black polygon 0,0 0,15 15,0 fill white circle 15,15 15,0' \( +clone -flip \) -compose Multiply -composite \( +clone -flop \) -compose Multiply -composite \) -alpha off -compose CopyOpacity -composite "${output_dir}${filename}_shadow.${extension}"
# calculating whitespace by dimension and our magic numbers
width=`/usr/local/bin/identify ${input_filename} | cut -f 3 -d " " | sed s/x.*//` # width
height=`/usr/local/bin/identify ${input_filename} | cut -f 3 -d " " | sed s/.*x//` # height
whitespace_bottom="$(echo "$width*0.042" | bc)"
whitespace_top="$(echo "$height*0.026" | bc)"
whitespace_sides="$(echo "$height*0.035" | bc)"
# generate shadow for image
/usr/local/bin/convert "${output_dir}${filename}_shadow.${extension}" \( +clone -background "${chosen_shadow}" -shadow 100x10+0+10 \) +swap -background none -layers merge +repage "${output_dir}${filename}_shadow.${extension}"
# generate whitespace for image
/usr/local/bin/convert "${output_dir}${filename}_shadow.${extension}" -bordercolor none -border 1 -gravity south -background none -splice "0x${whitespace_bottom}" "${output_dir}${filename}_shadow.${extension}"
/usr/local/bin/convert "${output_dir}${filename}_shadow.${extension}" -bordercolor none -border 1 -gravity north -background none -splice "0x${whitespace_top}" "${output_dir}${filename}_shadow.${extension}"
/usr/local/bin/convert "${output_dir}${filename}_shadow.${extension}" -bordercolor none -border 1 -gravity east -background none -splice "${whitespace_sides}x0" "${output_dir}${filename}_shadow.${extension}"
/usr/local/bin/convert "${output_dir}${filename}_shadow.${extension}" -bordercolor none -border 1 -gravity west -background none -splice "${whitespace_sides}x0" "${output_dir}${filename}_shadow.${extension}"
# copy generated image to clipboard
osascript -e "set the clipboard to (read (POSIX file \"${output_dir}${filename}_shadow.${extension}\") as JPEG picture)"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Steps -
Configuring the script
This script does the transformations to the given image to make it look very nice.
output_dir
in the script to the new folder you createdchmod +x drop-shadow.sh
Installing dependencies
first, you need to install brew
when you have brew, you can run the commands in step 1
brew update && brew install imagemagick && brew cask install copyq
(new version below doesn't require copyq)copyq.app
(new version below doesn't require copyq)Configuring keyboard maestro
(make sure you gave it full accessibility permissions just like with copyq)
congrats now when you take screenshots with command+shift+4 and select a portion of your screen, it will be a beautiful screenshot