Skip to main content

hey folks! this works! (you can make it burn any text you want of course -- just change the source of the $TEXT variable)

#!/bin/bash

## A script to burn Mac computer name into desktop background
## requires Imagemagick and Ghostscript which you can install with homebrew
## ljaeger 2022-07-28

 

BKGD="/path/to/current/desktop/picture.png" ## if only there was a way to get this programmatically! There isn't, I looked.

ORIG="$BKGD"_original.png ;

## get the ComputerName
TEXT=$(/usr/sbin/scutil --get ComputerName) ;

# make a backup of original desktop pic if none exists
if [ ! -f "$ORIG" ] ; then
/bin/cp "$BKGD" "$ORIG" ;
fi

# make a clean copy of desktop pic from backup
/bin/cp "$ORIG" "$BKGD" ;

# burn ComputerName into desktop pic with Imagemagick convert command
convert "$ORIG" -fill white -stroke black -font Helvetica -gravity North -pointsize 100 -annotate +0+25 "$TEXT" "$BKGD" ;

This is pretty cool, and got me wondering if there was a way to do the same without having to go for 3rd party tools. Turns out there is: macOS comes with something called sips, which has recently been updated with a Javascript API that can do all sorts of image manipulation! I found this unofficial documentation that shows what's possible: https://manicmaniac.github.io/sips-js-api/index.html

 

As for getting and setting the current desktop wallpaper, you can use https://github.com/scriptingosx/desktoppr - works great (yes I know I wrote "without 3rd party tools" 😅 - but this is so handy and practical to deploy, now being universal binary even!)

 

Here's a sample script I put together that works perfectly for burning the computer's name and serial in the bottom-left of the picture (coords would need adjusting according to the resolution of the original pic - mine was 1920x1200):

#!/bin/bash runAsUser() { if [[ $CURRENTUSER != "loginwindow" ]]; then uid=$(id -u "$CURRENTUSER") launchctl asuser $uid sudo -u $CURRENTUSER "$@" fi } ASSET_TAG=$(/usr/sbin/scutil --get ComputerName) SERIAL=$(system_profiler SPHardwareDataType | awk '/Serial Number/ { print $4 }') CURRENTUSER=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') CURRENT_WALLPAPER=$(runAsUser /usr/local/bin/desktoppr) cat <<'EOF' > /tmp/editBg.js const canvas = new Canvas(sips.images[0].size.width, sips.images[0].size.height); canvas.drawImage(sips.images.pop()); args = sips.arguments; canvas.font = '20pt AppleSDGothicNeo-SemiBold'; canvas.fillStyle = 'white'; canvas.fillText('Computer name:', 175, 900); canvas.fillText('Serial number:', 175, 925); canvas.font = '20pt AppleSDGothicNeo-Light'; canvas.fillText(args.pop(), 355, 900); canvas.fillText(args.pop(), 355, 925); const output = new Output(canvas, 'wallpaper-custom.png'); output.addToQueue(); EOF /usr/bin/sips -j /tmp/editBg.js -o /path/to/output/folder/ "$CURRENT_WALLPAPER" "$SERIAL" "$ASSET_TAG" rm /tmp/editBg.js if [[ -f /path/to/output/folder/wallpaper-custom.png ]]; then runAsUser /usr/local/bin/desktoppr /path/to/output/folder/wallpaper-custom.png else echo "Custom wallpaper not generated, something went wrong" exit 1 fi exit 0

 

 


This is pretty cool, and got me wondering if there was a way to do the same without having to go for 3rd party tools. Turns out there is: macOS comes with something called sips, which has recently been updated with a Javascript API that can do all sorts of image manipulation! I found this unofficial documentation that shows what's possible: https://manicmaniac.github.io/sips-js-api/index.html

 

As for getting and setting the current desktop wallpaper, you can use https://github.com/scriptingosx/desktoppr - works great (yes I know I wrote "without 3rd party tools" 😅 - but this is so handy and practical to deploy, now being universal binary even!)

 

Here's a sample script I put together that works perfectly for burning the computer's name and serial in the bottom-left of the picture (coords would need adjusting according to the resolution of the original pic - mine was 1920x1200):

#!/bin/bash runAsUser() { if [[ $CURRENTUSER != "loginwindow" ]]; then uid=$(id -u "$CURRENTUSER") launchctl asuser $uid sudo -u $CURRENTUSER "$@" fi } ASSET_TAG=$(/usr/sbin/scutil --get ComputerName) SERIAL=$(system_profiler SPHardwareDataType | awk '/Serial Number/ { print $4 }') CURRENTUSER=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') CURRENT_WALLPAPER=$(runAsUser /usr/local/bin/desktoppr) cat <<'EOF' > /tmp/editBg.js const canvas = new Canvas(sips.images[0].size.width, sips.images[0].size.height); canvas.drawImage(sips.images.pop()); args = sips.arguments; canvas.font = '20pt AppleSDGothicNeo-SemiBold'; canvas.fillStyle = 'white'; canvas.fillText('Computer name:', 175, 900); canvas.fillText('Serial number:', 175, 925); canvas.font = '20pt AppleSDGothicNeo-Light'; canvas.fillText(args.pop(), 355, 900); canvas.fillText(args.pop(), 355, 925); const output = new Output(canvas, 'wallpaper-custom.png'); output.addToQueue(); EOF /usr/bin/sips -j /tmp/editBg.js -o /path/to/output/folder/ "$CURRENT_WALLPAPER" "$SERIAL" "$ASSET_TAG" rm /tmp/editBg.js if [[ -f /path/to/output/folder/wallpaper-custom.png ]]; then runAsUser /usr/local/bin/desktoppr /path/to/output/folder/wallpaper-custom.png else echo "Custom wallpaper not generated, something went wrong" exit 1 fi exit 0

 

 


Cool, I thought about sips but didn't know it had an API for burning text!

I did try desktoppr but it seems to work only when a user is logged into the GUI. Can it return the default desktop pic for all users (including those who haven't logged in yet)?


Cool, I thought about sips but didn't know it had an API for burning text!

I did try desktoppr but it seems to work only when a user is logged into the GUI. Can it return the default desktop pic for all users (including those who haven't logged in yet)?


I never tried to use desktoppr without a user being logged in (or from the context of a different user, since our environment is one user per client). Reading the documentation I'd say it cannot, but it's worth experimenting.