Add support for viewing "images" such as Krita (.kra) files

* doc/emacs/files.texi (Image Mode): Document it.

* lisp/image/image-converter.el (image-converter-add-handler): New
function (bug#48415).
(image-convert): Use it.
This commit is contained in:
Lars Ingebrigtsen 2022-07-13 01:36:54 +02:00
parent fe50d914a9
commit 3b802f029e
2 changed files with 48 additions and 9 deletions

View file

@ -2355,6 +2355,25 @@ can be used to transform the image in question to @acronym{PNG} before
displaying. GraphicsMagick, ImageMagick and @command{ffmpeg} are
currently supported for image conversions.
@findex image-converter-add-handler
In addition, you may wish to add special handlers for certain image
formats. These can be added with the
@code{image-converter-add-handler} function. For instance, to allow
viewing Krita files as simple images, you could say something like:
@lisp
(image-converter-add
"kra"
(lambda (file)
(call-process "unzip" nil t nil
"-qq" "-c" "-x" file "mergedimage.png"))))
@end lisp
The function takes two parameters, where the first is a file name
suffix, and the second is a function to do the ``conversion''. This
function takes one parameter, the file name, and should output an
image in @code{image-convert-to-format} format in the current buffer.
@findex thumbs-mode
@cindex mode, Thumbs
The Image-Dired package can also be used to view images as

View file

@ -68,6 +68,8 @@ not, conversion will fail."
(imagemagick :command "convert" :probe ("-list" "format")))
"List of supported image converters to try.")
(defvar image-converter--extra-converters (make-hash-table :test #'equal))
(defun image-converter-initialize ()
"Determine the external image converter to be used.
This also determines which external formats we can parse."
@ -123,15 +125,21 @@ converted image data is returned as a string."
(error "IMAGE-FORMAT should be a symbol like `image/png'"))
(with-temp-buffer
(set-buffer-multibyte nil)
(when-let ((err (image-converter--convert
image-converter
(if (listp image)
(plist-get (cdr image) :file)
image)
(if (listp image)
(plist-get (cdr image) :data-p)
image-format))))
(error "%s" err))
(let* ((source (if (listp image)
(plist-get (cdr image) :file)
image))
(format (if (listp image)
(plist-get (cdr image) :data-p)
image-format))
(type (if format
(image-converter--mime-type format)
(file-name-extension source)))
(extra-converter (gethash type image-converter--extra-converters)))
(if extra-converter
(funcall extra-converter source)
(when-let ((err (image-converter--convert
image-converter source format)))
(error "%s" err))))
(if (listp image)
;; Return an image object that's the same as we were passed,
;; but ignore the :type value.
@ -298,6 +306,18 @@ Only suffixes that map to `image-mode' are returned."
"-")))))
"ffmpeg error when converting")))
(defun image-converter-add-handler (suffix converter)
"Make Emacs use CONVERTER to parse image files that end with SUFFIX.
CONVERTER is a function with one parameter, the file name. The
converter should output the image in the current buffer,
converted to `image-convert-to-format'."
(cl-pushnew suffix image-converter-file-name-extensions :test #'equal)
(setq image-converter-file-name-extensions
(sort image-converter-file-name-extensions #'string<))
(setq image-converter-regexp
(concat "\\." (regexp-opt image-converter-file-name-extensions) "\\'"))
(setf (gethash suffix image-converter--extra-converters) converter))
(provide 'image-converter)
;;; image-converter.el ends here