February 2, 2016 at 12:11 AM by Dr. Drang
As I buy more business supplies online and fewer in regular retail stores, I find myself taking more screenshots of digital receipts to attach to my expense reports. My SnapClip Keyboard Maestro macro (along with its predecesor scripts) has been my go-to utility for this, even though I originally wrote it mainly to capture screenshots of windows for posting here on the the blog. Because my pattern of use has changed, it seemed like a good time to give it a couple of tweaks to make it faster to use for its most common task.
The purpose of SnapClip is to give me a one-stop keyboard macro for screenshots that aren’t intended to be immediately uploaded to the leancrew server. It handles the following types of screenshot:
- Window screenshots, with or without a background border.
- Arbitrary rectangular area screenshots.
- Screenshots that should go only to the clipboard.
- Screenshots that should go both to the clipboard and a local file.
The changes I’ve made recently have been the addition of saving to a file and switching the default from window capture to rectangle capture. A small change in focus to better fit how I work now.
SnapClip is triggered by the ⌃⌥⌘4 keystroke combination. Like the built-in ⇧⌘4, it starts by presenting a crosshair for selecting a rectangular area but can be switched to window capture mode by tapping the spacebar. Once the rectangle or window has been selected, SnapClip presents the following dialog:
The defaults are to save the image to the clipboard only and to not add a blue background border. Strictly speaking, I don’t need SnapClip to handle this default condition. Using the standard ⇧⌘4 capture and holding down the Control key when making the selection will put the screenshot on the clipboard instead of saving it to a file. The advantage of SnapClip is that I can do more than the built-in screen capture with a single keystroke combination.
I generally don’t use the background border option when taking rectangular screenshots, but I do like adding the border when taking window screenshots. It changes the screenshot from this
Turning on the file saving option saves a copy of the screenshot to the Desktop with a filename in
yyyymmdd-HHMMSS.png format. I do this when I expect to need the screenshot more than once. I may, for example, paste it immediately into a tweet or text message but also expect to incorporate it into a blog post or an email later.
That’s what SnapClip does. Here’s how it’s made. It is, as I said, a Keyboard Maestro macro:
The only action in the macro is this Python script:
python: 1: #!/usr/bin/env python 2: 3: import Pashua 4: import tempfile 5: from PIL import Image 6: import sys, os 7: import subprocess 8: import shutil 9: from datetime import datetime 10: 11: # Local parameters 12: type = "png" 13: localdir = os.environ['HOME'] + "/Pictures/Screenshots" 14: tf, tfname = tempfile.mkstemp(suffix='.'+type, dir=localdir) 15: bgcolor = (61, 101, 156) 16: border = 16 17: desktop = os.environ['HOME'] + "/Desktop/" 18: fname = desktop + datetime.now().strftime("%Y%m%d-%H%M%S." + type) 19: 20: # Dialog box configuration 21: conf = ''' 22: # Window properties 23: *.title = Snapshot 24: 25: # Border checkbox properties 26: bd.type = checkbox 27: bd.label = Background border 28: bd.x = 10 29: bd.y = 60 30: 31: # Save file checkbox properties 32: sf.type = checkbox 33: sf.label = Save file to Desktop 34: sf.x = 10 35: sf.y = 35 36: 37: # Default button 38: db.type = defaultbutton 39: db.label = Clipboard 40: 41: # Cancel button 42: cb.type = cancelbutton 43: ''' 44: 45: # Capture a portion of the screen and save it to a temporary file. 46: status = subprocess.call(["screencapture", "-io", "-t", type, tfname]) 47: 48: # Exit if the user canceled the screencapture. 49: if not status == 0: 50: os.remove(tfname) 51: sys.exit() 52: 53: # Open the dialog box and get the input. 54: dialog = Pashua.run(conf) 55: if dialog['cb'] == '1': 56: os.remove(tfname) 57: sys.exit() 58: 59: # Add a desktop background border if asked for. 60: snap = Image.open(tfname) 61: if dialog['bd'] == '1': 62: # Make a solid-colored background bigger than the screenshot. 63: snapsize = tuple([ x + 2*border for x in snap.size ]) 64: bg = Image.new('RGB', snapsize, bgcolor) 65: bg.paste(snap, (border, border)) 66: bg.save(tfname) 67: 68: # Put the image on the clipboard, save to Desktop if asked for, 69: # and delete the temporary file. 70: impbcopy = os.environ['HOME'] + '/Dropbox/bin/impbcopy' 71: subprocess.call([impbcopy, tfname]) 72: if dialog['sf'] == '1': 73: shutil.copyfile(tfname, fname) 74: os.remove(tfname)
The script uses two nonstandard Python modules:
- Pashua, which provides bindings to Carsten Blüm’s lovely Pashua utility for creating dialog boxes from short textual descriptions.
- Image from the Python Imaging Library, which, as its name suggests, provides image editing commands.
The script also calls
impbcopy, Alec Jacobson’s command line utility for putting the contents of an image file onto the clipboard.
You’ll need all of these utilities and modules installed if you want to run your own SnapClip.
Most of the script was described in my post from last year. The differences between then and now are relatively minor:
- Lines 17–18 prepare the filename for saving to the Desktop.
- Lines 31–35 added the new file saving checkbox to the dialog.
- Line 46 starts the
screencapturecommand in rectangle mode instead of window mode.
- Lines 72–73 save the file to the Desktop if asked to do so.
If you’ve been reading ANIAT for any length of time, you’re sick of hearing me say this, but I’ll say it anyway. The great advantage of building your own tools is that you can make them fit exactly how you work. Even if how you work changes.