I did something similar, but using the standard library image capabilities of emacs instead of iimage mode. As a result, you don't need to have the mode enabled:
;; To know if I need to print as image or I need to default to the default eshell/cat
(defun my-is-imagep (filename)
(let ((extension (file-name-extension filename))
(image-extensions '("png" "jpg" "bmp")))
(member extension image-extensions)))
;; Creates a space with display properties. Feel free to change `eshell/println` to `insert` and use it in a normal emacs buffer, it will inline the path given in `file`.
(defun my-print-image-eshell (file)
(eshell/printnl (propertize " " 'display (create-image file))))
;; If image, use `my-print-image-eshell`. Otherwise, just use `eshell/cat`.
(defun eshell/mycat (&rest args)
(interactive)
(mapc (lambda (arg)
(if (my-is-imagep arg)
(my-print-image-eshell arg)
(eshell/cat arg)
)
) (-flatten args))
nil)
The key is to create some bogus output (a space in this case), add some magic display properties (read more here) and use eshell/printnl
to print that magic space that displays as your image.
Then, you can alias cat mycat $*
in your .emacs/eshell/alias
file.
You'll quickly face the problem of very big images slowing down emacs and not fitting in the screen, which forces the point to scroll down; they won't even show. This is some quick and dirty code that generates a thumbnail sized image for them and displays that instead. It could give you some ideas to implement something more robust (checking for errors, etc.). It requires imagemagick
to be installed. If you emacs was compiled with support for it, you don't need the shell commands and you can use library functions instead:
(defun my-is-imagep (filename)
(let ((extension (file-name-extension filename))
(image-extensions '("png" "jpg" "bmp")))
(member extension image-extensions)))
(defun my-get-image-width (filename)
(string-to-number
(shell-command-to-string
(format "convert '%s' -ping -format \"%%w\" info:" filename))))
(defun my-rescale-image (filename)
"Rescale an image to a maximum width, or leave untouched if already small. Returns the new file path."
(let ((file (make-temp-file "resized_emacs"))
(max-width 350))
(if (> (my-get-image-width filename) max-width)
(progn
(shell-command-to-string
(format "convert -resize %dx '%s' '%s'" max-width filename file))
file)
filename)))
(defun my-print-image-eshell (file)
(eshell/printnl (propertize " " 'display (create-image file))))
(defun eshell/mycat (&rest args)
(interactive)
(mapc (lambda (arg)
(if (my-is-imagep arg)
(my-print-image-eshell (my-rescale-image arg))
(eshell/cat arg)
)
) (-flatten args))
nil)