2025-12-15 Improving Emacs screenshots

Three years ago I wrote a short post about making screenshots directly in Emacs. I’m still using that feature from time to time (last time when I was writing the post about changing window layouts), and I noticed that it could use some improvement. Saving to ~/Pictures/Screenshots/ is less useful than saving to current directory, and the default filename is nice but sometimes I want to override it. More importantly, I often want my screenshots to be scaled down, so I decided to include a suitable option in frameshot. From now on, if I provide a width, the resulting image is scaled to that width.

So, here is an updated version.

(defvar frameshot-format 'png
  "Default frame shot format.")

(defun frameshot (filename width)
  "Save Emacs frame as frame shot."
  (interactive (list (read-file-name
                      "Frameshot file: "
                      nil nil nil
                      (concat (format-time-string
                               "Screenshot-%Y-%m-%d-%T.")
                              (symbol-name frameshot-format)))
                     (read-string "Rescale to [px]: ")))
  (with-temp-file filename
    (insert (x-export-frames nil (or frameshot-format 'png))))
  (when width
      (shell-command (format "mogrify -resize %s %s" width filename)))
  (message "Frameshot saved as `%s'" filename))

The initial parameter to read-file-name is not recommended, but in my case it was exactly what I wanted. Note that there is no error checking whatsoever – if I provide a width of -42 or even, say, lol, the resizing will just silently fail. That’s ok, it’s just a tool I’m coding for myself, not a production-grade package ready to be released.

The nicest thing is that it took me less than 15 minutes to come up with a simple piece of code solving a real problem. As usual, Emacs proves itself to be an extremely malleable environment, enabling rapid developing of useful little tools.

CategoryEnglish, CategoryBlog, CategoryEmacs