14

When an image has a transparent background, Emacs of course respects that.

Unfortunately, this can lead to issues with display:

black text on dark background

Is there a way to display a specific color (e.g. white) behind the image? There appears to be some support for it in ImageMagick images.

The specific stuff I'm working with right now can have the background color set, however I have to add an extra few lines to every single figure in order to do that, which is less than ideal. I would like to get it to where inline images displayed in org-mode have the background color set by default.

(Note: this isn't org-babel specific, it just happens to be how I'm getting these images right now)

Drew
  • 75,699
  • 9
  • 109
  • 225
J David Smith
  • 2,635
  • 1
  • 16
  • 27

2 Answers2

10

After much digging, there does not appear to be a built-in option to adjust this in Org or in general. The image system does not have any way to customize the default background, and org doesn't have a way to set the :background property. However, it does look like most images support the :background display property.

I added this functionality to Org by modifying (read: copy and paste into .emacs.d with a 1-line change) org-display-inline-images.

I won't reproduce the function here, because it is rather lengthy. Line 51 of the function reads:

(setq img (save-match-data (create-image file type nil :width width)))

I defined a new customizable variable org-inline-image-background, which can hold either nil (transparent background) or a color:

(defcustom org-inline-image-background nil
  "The color used as the default background for inline images.
  When nil, use the default face background."
  :group 'org
  :type '(choice color (const nil)))

Then, I added it to line 51:

(setq img (save-match-data (create-image file type nil :width width 
                                                       :background org-inline-image-background)))

This works beautifully and it can be customized using the color picker, so it satisfies all my requirements.

black text light background

J David Smith
  • 2,635
  • 1
  • 16
  • 27
  • 2
    Looks like you put in a lot of work to figure this thing out. Would you like to submit a patch for this or request this to be added to org-mode by emailing emacs-orgmode@gnu.org? – Kaushal Modi Feb 26 '16 at 02:25
  • Once I put it through its paces (make sure it doesn't break anything) I'm hoping too. – J David Smith Feb 26 '16 at 16:04
  • The new Org-mode version 8.0 seems start use overlay to display inline images, Is there a way to modify overlay default background color? – stardiviner Mar 17 '16 at 02:29
  • @stardiviner that is exactly what this does – J David Smith Mar 17 '16 at 17:10
  • I checked my Org version, it is `8.3.4`. I checked the `org-display-inline-images` source code, have not found your code definition. Here is the source code: https://gist.github.com/649a7b36031d6adb4a96 – stardiviner Mar 18 '16 at 12:24
  • I find the `create-image` line code, then append code as your method. I think this should be an advice. Can you improve your code? – stardiviner Mar 18 '16 at 12:30
  • @stardiviner: no. If you want it as advice, you can use :filter-return (https://www.gnu.org/software/emacs/manual/html_node/elisp/Advice-combinators.html#Advice-combinators) to do it. – J David Smith Mar 21 '16 at 13:50
  • @JDavidSmith I think this should use `:filter-args` on `create-image` to specify the background color get from the color-theme. But I still can't figure it out how to write this advice. – stardiviner Jan 06 '18 at 09:58
7

I got a better solution with advice.

(defcustom org-inline-image-background nil
  "The color used as the default background for inline images.
When nil, use the default face background."
  :group 'org
  :type '(choice color (const nil)))

(defun create-image-with-background-color (args)
  "Specify background color of Org-mode inline image through modify `ARGS'."
  (let* ((file (car args))
         (type (cadr args))
         (data-p (caddr args))
         (props (cdddr args)))
    ;; Get this return result style from `create-image'.
    (append (list file type data-p)
            (list :background (or org-inline-image-background (face-background 'default)))
            props)))

(advice-add 'create-image :filter-args
            #'create-image-with-background-color)
Stefan
  • 26,154
  • 3
  • 46
  • 84
stardiviner
  • 1,888
  • 26
  • 45
  • Nice solution. Might I suggest renaming the advice function to remove the `org-` prefix since the solution applies much more broadly? With non-default themes, the goal is probably a white background (which is frequently not the default face background), so `(list :background "white")` might be a useful example. – ebpa Sep 30 '19 at 02:07
  • 1
    That is user's option, your consider is right. I think your comment is enough for user who found this code. :) – stardiviner Sep 30 '19 at 03:30
  • Does this still work for you? For me this only seems to work for SVG images with a transparent background, it's not affecting PNG images. I'm using Emacs 29.0.60 on macOS with Org version 9.6.1. – gsgx Jun 16 '23 at 19:51