It seems like this should be pretty straightforward since Emacs knows how to display images.

In a buffer, let's say I have a URL to an image like:


I'd like to put the caret on that url, call a function like expand-image-from-url and have it render the image in-line.

Is this something that's easily possible?


If you don't mind the image being displayed in a different buffer, just do

M-x ffap

If you insist on the image appearing in the current buffer, you'll need to do just a little more work:

(require 'url)

(defun insert-image-from-url (&optional url)
  (unless url (setq url (url-get-url-at-point)))
  (unless url
    (error "Couldn't find URL."))
  (let ((buffer (url-retrieve-synchronously url)))
         (let ((data (with-current-buffer buffer
                       (goto-char (point-min))
                       (search-forward "\n\n")
                       (buffer-substring (point) (point-max)))))
           (insert-image (create-image data nil t)))
      (kill-buffer buffer))))
  • That's the thing, I want it displayed inline in the same buffer. – bitops May 2 '15 at 21:30
  • 1
    You're a tough customer. Edited with some sample code. – jch May 2 '15 at 21:33
  • Very nice! One thing to note: I had to grab some of the 'thingatpt' packages to get it to work. I suppose url-get-url-at-point is not a built-in command. – bitops May 2 '15 at 23:00
  • 1
    You just need (require 'url). – jch May 2 '15 at 23:03
  • Thank you! Works perfectly. – giessel May 2 at 19:05

You can use the following rewritten function to display inline images as well as web image (exactly like the way to show inline images)in Org-mode (if your work environment is in Org-mode).

  1. when display inline image, it will generate a thumb file to local disk and display it. By using this, you can annotate your image as free as you can without damaging your original image.
  2. when display url image, it will save the image to a variable and display it without any download.

Any extension can be possible. Of course you can display the inline image but not generating the thumb file by slightly change. But I prefer the above way.

(defun org-display-inline-images (&optional include-linked refresh beg end)
  "Display inline and url images.
Normally only links without a description part are inlined, because this
is how it will work for export.  When INCLUDE-LINKED is set, also links
with a description part will be inlined.  This
can be nice for a quick
look at those images, but it does not reflect what exported files will look
When REFRESH is set, refresh existing images between BEG and END.
This will create new image displays only if necessary.
BEG and END default to the buffer boundaries."
  (interactive "P")
  (unless refresh
    (if (fboundp 'clear-image-cache) (clear-image-cache)))
      (setq beg (or beg (point-min)) end (or end (point-max)))
      (goto-char beg)
      (let ((re (concat "\\(\\(http\\)\\|\\(\\[\\[\\(\\(file:\\)\\|\\([./~]\\)\\)\\)\\)\\([^]\n]+?"
                    (substring (org-image-file-name-regexp) 0 -2)
                    "\\)" (format "\\(\\(\\]%s\\)\\|\\)" (if include-linked "" "\\]"))))
        old file ov img width point-begin point-end)
    (while (re-search-forward re end t)
      (setq old (get-char-property-and-overlay (match-beginning 1)
            match (match-string-no-properties 0)
            point-begin (match-beginning 0)
            point-end (match-end 0))
      (if (s-starts-with? "http" match)
            (let* ((buffer (url-retrieve-synchronously match))
                       (let ((data (with-current-buffer buffer
                                     (goto-char (point-min))
                                     (search-forward "\n\n")
                                     (buffer-substring (point) (point-max)))))
                         (require 'image+)
                         (setq img (imagex--fit-to-size (create-image data 'jpeg t) 400 400)))))))
        (setq file (expand-file-name
                    (concat (or (match-string 6) "") (match-string 7)))
              width (if (eq (car (org-element-property :parent (org-element-at-point))) 'table) 200 400))
        (when (file-exists-p file)
          (let ((file-thumb (format "%s%s_thumb.png" (file-name-directory file) (file-name-base file))))
            (if (file-exists-p file-thumb)
                (let ((thumb-time (nth 5 (file-attributes file-thumb 'string)))
                      (file-time (nth 5 (file-attributes file 'string))))
                  (if (time-less-p thumb-time file-time)
                      (shell-command (format org-imagemagick-display-command
                                             file width width file-thumb) nil nil)))
              (shell-command (format org-imagemagick-display-command
                                     file width width file-thumb) nil nil))
            (if (and (car-safe old) refresh)
                (image-refresh (overlay-get (cdr old) 'display))
              (setq img (save-match-data (create-image file-thumb)))))))
      (when img
        (setq ov (make-overlay point-begin point-end))
        (overlay-put ov 'display img)
        (overlay-put ov 'face 'default)
        (overlay-put ov 'org-image-overlay t)
        (overlay-put ov 'modification-hooks
                     (list 'org-display-inline-remove-overlay))
        (push ov org-inline-image-overlays)))))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.