A Tiny Header line Tweak: Image Dimensions in image mode

I have been doing a lot of fiddling with images lately, mostly through dired and image-dired, and one little thing has been bugging me for a while. When I open an image in Emacs, image-mode happily shows me the picture, but it never tells me the one bit of information I actually want to know, how big is the thing?, width, height, file size, that sort of thing. You can of course bounce out to a shell and run identify or file, but that feels silly when Emacs already has the image loaded

20260430074958-emacs--A-Tiny-Header-line-Tweak-Image-Dimensions-in-image-mode.jpg

So I thought, right, this should be a five minute job, just slap something into the header-line on image-mode-hook and be done with it. And it more or less was, although there was a small wrinkle along the way that is worth mentioning, because it caught me out.

Here is what ended up in my init.el:

;;
;; -> image-mode-dimensions
;;

(defun my/image-mode-show-dimensions ()
  "Display the open image's pixel dimensions and file size in the header line."
  (when (and (derived-mode-p 'image-mode)
             buffer-file-name
             (file-exists-p buffer-file-name))
    (condition-case err
        (let* ((image (or (image-get-display-property)
                          (create-image buffer-file-name)))
               (size (image-size image t))
               (width (car size))
               (height (cdr size))
               (bytes (file-attribute-size
                       (file-attributes buffer-file-name))))
          (setq header-line-format
                (format " %d x %d px   %s"
                        width height
                        (file-size-human-readable bytes))))
      (error
       (setq header-line-format
             (format " image dimensions unavailable: %S" err))))))

(add-hook 'image-mode-hook #'my/image-mode-show-dimensions)
(add-hook 'image-mode-new-window-functions
          (lambda (&rest _) (my/image-mode-show-dimensions)))

A few notes on what is going on here. The or around image-get-display-property and create-image means we use the displayed image spec when it is there (cheaper, no extra file read), and fall back to building one from the file path when it is not. image-size with a non-nil second argument returns dimensions in actual pixels rather than canvas units, which is what I want. file-size-human-readable gives me a nice 2.4M rather than 2516582, because nobody reads bytes directly.

The condition-case is there because images can occasionally throw, especially when something has gone wrong with imagemagick or an unsupported format sneaks in, and I would rather see a polite header-line message than have the hook explode and pollute *Messages* every time I open a picture.

The second hook, image-mode-new-window-functions, is the one that handles the case where you flip between image and text view of the same buffer with C-c C-c, since the image gets re-displayed and the header-line needs to refresh too.

So now when I pop open an image, I get a nice little header-line that reads something like:

1920 x 1080 px   2.4M

A small thing, but the kind of small thing that makes Emacs feel like it fits a bit more snugly around how I actually work.