├── LICENSE ├── Print Label.workflow └── Contents │ ├── Info.plist │ ├── QuickLook │ └── Preview.png │ └── document.wflow ├── README.md └── images ├── install-finder-browse.png ├── reference-automator-device-name.png ├── reference-rename-printer.png ├── reference-system-settings-printer-options.png ├── reference-system-settings-printer.png ├── usage-print-dialog-menu.png └── usage-print-dialog.png /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 John Stephens 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Print Label.workflow/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleName 6 | Print Label 7 | 8 | 9 | -------------------------------------------------------------------------------- /Print Label.workflow/Contents/QuickLook/Preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/john-stephens/zebra-mac-label-automator/440369fc02e354daed3fcfe6220fa90bdd1b45c2/Print Label.workflow/Contents/QuickLook/Preview.png -------------------------------------------------------------------------------- /Print Label.workflow/Contents/document.wflow: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AMApplicationBuild 6 | 523 7 | AMApplicationVersion 8 | 2.10 9 | AMDocumentVersion 10 | 2 11 | actions 12 | 13 | 14 | action 15 | 16 | AMAccepts 17 | 18 | Container 19 | List 20 | Optional 21 | 22 | Types 23 | 24 | com.apple.cocoa.string 25 | 26 | 27 | AMActionVersion 28 | 2.0.3 29 | AMApplication 30 | 31 | Automator 32 | 33 | AMParameterProperties 34 | 35 | COMMAND_STRING 36 | 37 | CheckedForUserDefaultShell 38 | 39 | inputMethod 40 | 41 | shell 42 | 43 | source 44 | 45 | 46 | AMProvides 47 | 48 | Container 49 | List 50 | Types 51 | 52 | com.apple.cocoa.string 53 | 54 | 55 | ActionBundlePath 56 | /System/Library/Automator/Run Shell Script.action 57 | ActionName 58 | Run Shell Script 59 | ActionParameters 60 | 61 | COMMAND_STRING 62 | PRINTER="" # Auto-detect by default 63 | 64 | IDENTIFY="/opt/homebrew/bin/identify" 65 | MAGICK="/opt/homebrew/bin/magick" 66 | PDFTOPPM="/opt/homebrew/bin/pdftoppm" 67 | PDFINFO="/opt/homebrew/bin/pdfinfo" 68 | 69 | # Utility function to show an error message 70 | show_error() { 71 | osascript -e "display dialog \"$1\"" 72 | } 73 | 74 | if [ -z "$PRINTER" ]; then 75 | # Auto-detect the printer by looking for one that starts with "Zebra" 76 | device_names=($(lpstat -p | awk '{print $2}')) 77 | 78 | for device_name in "${device_names[@]}"; do 79 | if lpstat -l -p "$device_name" | grep -q "Description: Zebra"; then 80 | PRINTER="$device_name" 81 | fi 82 | done 83 | 84 | if [ -z "$PRINTER" ]; then 85 | show_error "Failed to auto-detect your Zebra printer.\n\nPlease set the \$PRINTER setting." 86 | exit 87 | fi 88 | else 89 | # Check that the specified printer exists 90 | if ! lpstat -p "$PRINTER"; then 91 | show_error "Printer \\\"$PRINTER\\\" not found.\n\nPlease check the \$PRINTER setting." 92 | exit 93 | fi 94 | fi 95 | 96 | # Check that the required apps are installed 97 | required_commands=("$IDENTIFY" "$MAGICK" "$PDFTOPPM" "$PDFINFO") 98 | 99 | for cmd in "${required_commands[@]}"; do 100 | if ! command -v "$cmd" > /dev/null 2>&1; then 101 | show_error "\\\"$cmd\\\" not found.\n\nPlease verify that it is installed." 102 | exit 103 | fi 104 | done 105 | 106 | # Determine the printer resolution 107 | dpi="$(lpoptions -p "$PRINTER" -l | grep "^Resolution" | sed -E "s/^.*\*([0-9]+)dpi.*/\1/g")" 108 | 109 | # Verify that we got a proper resolution value 110 | if [[ ! "$dpi" =~ ^[0-9]+$ ]]; then 111 | show_error "Failed to determine the printer DPI!" 112 | exit 113 | fi 114 | 115 | for f in "$@"; do 116 | # Determine the media to use based on the label size (assumes all pages are the same) 117 | read width height resolution <<< "$($IDENTIFY -format "%w %h %x\n" "$f" | head -n 1)" 118 | 119 | page_width="$(printf "%.0f" "$(echo "$width / $resolution * 72" | bc -l)")" 120 | page_height="$(printf "%.0f" "$(echo "$height / $resolution * 72" | bc -l)")" 121 | media="w${page_width}h${page_height}" 122 | 123 | # Determine the available media options 124 | available_media=$(lpoptions -p "$PRINTER" -l | \ 125 | grep "^PageSize/Media Size:" | \ 126 | cut -d: -f2 | \ 127 | tr ' ' '\n' | \ 128 | sed 's/^\*//' 129 | ) 130 | 131 | # Validate that the media exists or use a custom media if supported 132 | if ! echo "$available_media" | grep -qw "$media"; then 133 | if echo "$available_media" | grep -qw "Custom.WIDTHxHEIGHT"; then 134 | media="Custom.${page_width}x${page_height}" 135 | else 136 | show_error "Failed to determine the printer media! ($media, $width, $height, $resolution)" 137 | exit 138 | fi 139 | fi 140 | 141 | # Create a temp dir to extract all of the pages into 142 | tmpdir=$(mktemp -d) 143 | 144 | if [[ "$?" -gt 0 ]]; then 145 | show_error "Failed to create temp dir!" 146 | exit 147 | fi 148 | 149 | # Extract all of the pages 150 | $PDFTOPPM -r $dpi -aa no -aaVector no -gray "$f" $tmpdir/page 151 | 152 | # Apply thresholding to all pages and spool to the printer 153 | $MAGICK $tmpdir/page* -colorspace gray -color-threshold 'gray(50%)-gray(100%)' -density $dpi -compress none pdf:- | lpr -P "$PRINTER" -o portrait -o media="$media" 154 | 155 | # Cleanup 156 | rm -rf "$tmpdir" 157 | done 158 | 159 | CheckedForUserDefaultShell 160 | 161 | inputMethod 162 | 1 163 | shell 164 | /bin/bash 165 | source 166 | 167 | 168 | BundleIdentifier 169 | com.apple.RunShellScript 170 | CFBundleVersion 171 | 2.0.3 172 | CanShowSelectedItemsWhenRun 173 | 174 | CanShowWhenRun 175 | 176 | Category 177 | 178 | AMCategoryUtilities 179 | 180 | Class Name 181 | RunShellScriptAction 182 | InputUUID 183 | 9995A684-AC43-46F6-BDF1-4BD32DCF6FDA 184 | Keywords 185 | 186 | Shell 187 | Script 188 | Command 189 | Run 190 | Unix 191 | 192 | OutputUUID 193 | 358FF942-92EC-4617-A219-D6831B15B811 194 | UUID 195 | 06153228-5369-4BE5-96BA-9393AB6CCE0F 196 | UnlocalizedApplications 197 | 198 | Automator 199 | 200 | arguments 201 | 202 | 0 203 | 204 | default value 205 | 0 206 | name 207 | inputMethod 208 | required 209 | 0 210 | type 211 | 0 212 | uuid 213 | 0 214 | 215 | 1 216 | 217 | default value 218 | 219 | name 220 | CheckedForUserDefaultShell 221 | required 222 | 0 223 | type 224 | 0 225 | uuid 226 | 1 227 | 228 | 2 229 | 230 | default value 231 | 232 | name 233 | source 234 | required 235 | 0 236 | type 237 | 0 238 | uuid 239 | 2 240 | 241 | 3 242 | 243 | default value 244 | 245 | name 246 | COMMAND_STRING 247 | required 248 | 0 249 | type 250 | 0 251 | uuid 252 | 3 253 | 254 | 4 255 | 256 | default value 257 | /bin/sh 258 | name 259 | shell 260 | required 261 | 0 262 | type 263 | 0 264 | uuid 265 | 4 266 | 267 | 268 | isViewVisible 269 | 1 270 | location 271 | 529.000000:602.000000 272 | nibPath 273 | /System/Library/Automator/Run Shell Script.action/Contents/Resources/Base.lproj/main.nib 274 | 275 | isViewVisible 276 | 1 277 | 278 | 279 | connectors 280 | 281 | workflowMetaData 282 | 283 | workflowTypeIdentifier 284 | com.apple.Automator.printPlugin 285 | 286 | 287 | 288 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zebra Thermal Printer Mac Automator Workflow 2 | 3 | ## Introduction 4 | 5 | Can you get a high quality label out of your Zebra thermal printer on your Mac without paying for expensive software? Yes! 6 | 7 | The Zebra printer is very picky about image size and colors that are not black or white. Simply resizing your label or using anti-aliasing will introduce gray colors and result in a blurry print. Your label may even have gray colors to begin with. 8 | 9 | I fixed this by creating an Automator workflow that uses Poppler and ImageMagic to remove the gray colors by applying thresholding. The result is a nice crisp label! 10 | 11 | ## Tested Printers 12 | 13 | - GK420d 14 | - GX420d 15 | - LP2844 16 | - ZD230 17 | - ZD420 18 | - ZD621D 19 | 20 | If it works (or doesn't work) for the model you have, I would appreciate your feedback so that I can fill in the list of tested printers and add support if needed. Head over to the [Discussions](https://github.com/john-stephens/zebra-mac-label-automator/discussions) section and let me know. 21 | 22 | ## Pre-requisites 23 | 24 | 1. Your Zebra printer has already been set up. See: [Install CUPS Driver for Zebra Printer in Mac OS](https://supportcommunity.zebra.com/s/article/Install-CUPS-driver-for-Zebra-Printer-in-Mac-OS) 25 | 2. Poppler and ImageMagick have been installed. It is assumed that these have been installed using [Homebrew](https://brew.sh). (`brew install poppler imagemagick`) 26 | 27 | ## Installation and Setup 28 | 29 | 1. Download and unzip [Print Label.workflow.zip](//github.com/john-stephens/zebra-mac-label-automator/releases/latest/download/Print.Label.workflow.zip) 30 | 2. From Finder browse to `~/Library` 31 | 32 | - Click on the Finder app 33 | - Click Go > Go to Folder... (⇧ ⌘ G) 34 | - Enter "~/Library" and press Enter 35 | 36 | ![Browse in Finder](images/install-finder-browse.png) 37 | 38 | 3. Create a folder named `PDF Services` if it does not already exist 39 | 4. Drag `Print Label.workflow` (extension may be hidden) into the `PDF Services` folder. You are all set! 40 | 41 | ## Usage 42 | 43 | ### General 44 | 45 | 1. Open the label you want to print. (If you need to crop, I recommend opening the label in Preview: click the Markup button, click the selection tool, select the area you want to print, click Tools > Crop (⌘ K)) 46 | 2. Go to print your label, but don’t actually print. This should be done using the system print dialog. 47 | 3. Select your Zebra printer as the printer you want to print from. 48 | 4. Set the paper size to label size you are using. (i.e. 4x6in) 49 | 5. Make sure the preview matches how you want your label printed. 50 | ![Print dialog](images/usage-print-dialog.png) 51 | 6. From the dropdown on the bottom-left, click "Print Label". 52 | ![Print dialog menu](images/usage-print-dialog-menu.png) 53 | 54 | ### Chrome 55 | 56 | Chrome has its own print dialog which does not make the Automation workflows available. While Chrome does have a "Print using System Dialog" option, there is no preview and it occasionally does not trigger the Automation workflows when selected. 57 | 58 | 1. Start the process to print your label. 59 | 2. Select your Zebra printer as the printer you want to print from. 60 | 3. Set the paper size to label size you are using. (i.e. 4x6in) 61 | 4. Click "Open in Preview" option from the print dialog. 62 | 5. Follow the [General](#general) process above. 63 | 64 | ## Troubleshooting 65 | 66 | ### Error: "Failed to auto-detect your Zebra printer." 67 | 68 | The workflow is trying to find a printer name that starts with "Zebra" and doesn't find it. There could be two reasons for this: 69 | 70 | 1. The driver for your Zebra printer is not installed. See: [Install CUPS Driver for Zebra Printer in Mac OS](https://supportcommunity.zebra.com/s/article/Install-CUPS-driver-for-Zebra-Printer-in-Mac-OS) 71 | 2. The name of your Zebra printer does not start with "Zebra". You have two options here: 72 | 73 | a. Rename your Zebra printer so that it starts with "Zebra". See [Renaming your printer](#renaming-your-printer). 74 | 75 | b. Set the `PRINTER` value in the workflow with your Zebra printer's device name. See [Editing the `PRINTER` value](#editing-the-printer-value). 76 | 77 | ### The workflow prints to the wrong Zebra printer 78 | 79 | The workflow is trying to find a printer name that starts with "Zebra" and it is picking the wrong one because there are multiple. You have a few options in this case: 80 | 81 | a. Rename the other printer so that the one you want to print to is the only one with a name that starts with "Zebra". See [Renaming your printer](#renaming-your-printer). 82 | 83 | b. If only one device you want to print to, set the `PRINTER` value in the workflow with that Zebra printer's device name. See [Editing the `PRINTER` value](#editing-the-printer-value). 84 | 85 | c. If you want to print to multiple Zebra printers, make a copy of `Print Label.workflow`, one for each printer, and set the `PRINTER` value for each copy with the corresponding Zebra printer's device name. Make sure that you set the workflow to an appropriate filename so that you know which workflow corresponds to which printer. See [Editing the `PRINTER` value](#editing-the-printer-value). 86 | 87 | ### Error: "Printer "{YOUR-PRINTER-NAME}" not found." 88 | 89 | The `PRINTER` value at the top of the workflow was not set to the correct printer device name. Make sure that you have the correct device name value. See [Getting the device name for your printer](#getting-the-device-name-for-your-printer) and [Editing the `PRINTER` value](#editing-the-printer-value). 90 | 91 | ### Error: "Failed to determine the printer DPI!" 92 | 93 | The workflow tried to read the printer options and didn't find a matching "Resolution" option. If this happens, I would appreciate feedback. Drop a comment in the [Discussions](https://github.com/john-stephens/zebra-mac-label-automator/discussions) section with the output of `lpstat -p | awk '{print $2}' | xargs -t -n1 -I {} lpoptions -p {} -l`. 94 | 95 | ### Error: "Failed to determine the printer media!" 96 | 97 | The workflow tried to determine the appropriate media value based on the page size, but couldn't find a match for your printer. If this happens, I would appreciate feedback. Drop a comment in the [Discussions](https://github.com/john-stephens/zebra-mac-label-automator/discussions) section with the output of `lpstat -p | awk '{print $2}' | xargs -t -n1 -I {} lpoptions -p {} -l 98 | `. 99 | 100 | ### Error: ""identify" not found" or ""magick" not found" 101 | 102 | This will happen if `identify` or `magick` are not found. This could either be because ImageMagick is not installed or was not installed with [Homebrew](https://brew.sh). You have two options in this case: 103 | 104 | a. Install ImageMagick with [Homebrew](https://brew.sh). 105 | 106 | b. Correct the path for `identify` or `magick` at the top of `Print Label.workflow`. 107 | 108 | ### Error: ""pdftoppm" not found" or ""pdfinfo" not found" 109 | 110 | This will happen if `pdftoppm` or `pdfinfo` are not found. This could either be because Poppler is not installed or was not installed with [Homebrew](https://brew.sh). You have two options in this case: 111 | 112 | a. Install Poppler with [Homebrew](https://brew.sh). 113 | 114 | b. Correct the path for `pdftoppm` or `pdfinfo` at the top of `Print Label.workflow`. 115 | 116 | ## Reference 117 | 118 | ### Getting the device name for your printer 119 | 120 | 1. Go to System Settings > Printers & Scanners 121 | 2. Click on your Zebra printer. 122 | 123 | ![Zebra printer dialog](images/reference-system-settings-printer.png) 124 | 125 | 3. Click "Options & Supplies" 126 | 4. Copy the "Device Name" value 127 | 128 | ![Zebra printer device name](images/reference-system-settings-printer-options.png) 129 | 130 | ### Editing the `PRINTER` value 131 | 132 | 1. Browse to the `PDF Services` folder. 133 | 134 | - Click on the Finder app 135 | - Click Go > Go to Folder... (⇧ ⌘ G) 136 | - Enter "~/Library/PDF Services" and press Enter 137 | 138 | 2. Double-click on `Print Label.workflow` (extension may be hidden) to open it in Automator. 139 | 4. At the top, fill in your device name as the value for `PRINTER`. See [Getting the device name for your printer](#getting-the-device-name-for-your-printer). 140 | 141 | ![Paste device name](images/reference-automator-device-name.png) 142 | 143 | 5. Save the workflow. 144 | 145 | ### Renaming your printer 146 | 147 | - Go to System Settings > Printers & Scanners 148 | - Click on your printer. 149 | - Change the name of your printer by typing in the "Name" field. 150 | - Click "Done" 151 | 152 | ![Rename printer](images/reference-rename-printer.png) 153 | -------------------------------------------------------------------------------- /images/install-finder-browse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/john-stephens/zebra-mac-label-automator/440369fc02e354daed3fcfe6220fa90bdd1b45c2/images/install-finder-browse.png -------------------------------------------------------------------------------- /images/reference-automator-device-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/john-stephens/zebra-mac-label-automator/440369fc02e354daed3fcfe6220fa90bdd1b45c2/images/reference-automator-device-name.png -------------------------------------------------------------------------------- /images/reference-rename-printer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/john-stephens/zebra-mac-label-automator/440369fc02e354daed3fcfe6220fa90bdd1b45c2/images/reference-rename-printer.png -------------------------------------------------------------------------------- /images/reference-system-settings-printer-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/john-stephens/zebra-mac-label-automator/440369fc02e354daed3fcfe6220fa90bdd1b45c2/images/reference-system-settings-printer-options.png -------------------------------------------------------------------------------- /images/reference-system-settings-printer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/john-stephens/zebra-mac-label-automator/440369fc02e354daed3fcfe6220fa90bdd1b45c2/images/reference-system-settings-printer.png -------------------------------------------------------------------------------- /images/usage-print-dialog-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/john-stephens/zebra-mac-label-automator/440369fc02e354daed3fcfe6220fa90bdd1b45c2/images/usage-print-dialog-menu.png -------------------------------------------------------------------------------- /images/usage-print-dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/john-stephens/zebra-mac-label-automator/440369fc02e354daed3fcfe6220fa90bdd1b45c2/images/usage-print-dialog.png --------------------------------------------------------------------------------