presenterm icon indicating copy to clipboard operation
presenterm copied to clipboard

SVG support

Open arvid-norlander opened this issue 7 months ago • 6 comments

Error loading presentation: 

could not load image 'logo.svg' at 13:1: image decoding: The image format could not be determined

I would have expected rastering of SVGs to PNGs to be handled internally by presentterm. This would be useful as I need to use the logo at different sizes on different slides.

Also, this would handle transparency better, as exporting to png from inkscape seems to do the wrong blending mode towards the terminal background colour (the image is getting a white fringe).

  • presenterm 0.14.0
  • Installed with cargo install
  • Rust 1.87.0 (installed with rustup)
  • Ubuntu 24.04 LTS

arvid-norlander avatar Jun 02 '25 08:06 arvid-norlander

~~Actually, inspecting the png it seems the white fringe is not an issue from inkscape but rather with presenterm's alpha blending of pngs in certain situations. I'll open a separate bug report for that.~~ Nevermind, it seems to be inkscape's fault.

arvid-norlander avatar Jun 02 '25 08:06 arvid-norlander

Not supporting SVGs was a decision made to avoid bloating the binary with not so used image formats (which applies to SVGs given you're the first person to bring this up). Depending on the image protocol you use the images are converted to PNGs before printing anyway.

Is keeping the image as PNG but using the image size specifier not work for you?

mfontanini avatar Jun 02 '25 13:06 mfontanini

Scaling a bitmap causes artifacts, unlike scaling a vector graphics image, that is the main reason for this. Plus it would simplify my workflow, as I normally have a lot of vector graphics (graphs, plots, etc). This means that for the highest quality you have to display at 1:1 pixel scaling and do any scaling in the step before (when you convert to png).

Also, (though this is probably the fault of inkscape export), I get white artifacts like this, if I use a transparent png of the svg exported with inkscape. If I set the matching background colour in inkscape before export, I don't get the fringing.

Image

while I would expect this (exported with background colour matching the presentation):

Image

It is probably inkscape that is at fault, because if I use ImageMagick to convert I get a blurry mess instead (but no fringing):

Image

In all cases the images are set to be the same with and these are displayed at native size. Things get worse at non-native size of course. The SVG uses paths (not embedded text & fonts) so I would expect identical rendering and correct alpha blending, but that is not the case apparently.

I also tried the first hit for a rust crate for rendering svg I found: resvg, and it renders the SVG correctly and sharply:

Image

So it seems a high quality Rust crate is already available for this.


Now, I understand you concern as well. But here is an idea. You already have support for calling a command and using the output for code listings. What about adding support for making such a code block return a png instead? If given code is the expected width in terms of pixels (maybe via en environment variable or such), this would allow me to do something like:

```bash +exec-to-image
resvg -w $PIXEL_WIDTH mylogo.svg /dev/stdout
```

This could potentially be useful also for other features, such as rendering diagrams on the fly (other than mermaid). I think there is potential to do interesting things with animated images etc using this as well in the future.

arvid-norlander avatar Jun 02 '25 14:06 arvid-norlander

Another option would be to add support for calling out to resvg specifically, just like I had to install weasyprint for PDF export. That might be easier.

arvid-norlander avatar Jun 02 '25 14:06 arvid-norlander

I have two thoughts:

  1. Based on my understanding of the terminal image protocols, they rasterise to a specific size to display anyway - so you may not be able to get your beautiful vector dreams, even if functionality were added to presenterm.
  2. I think you can prototype what you want TODAY with clever use of exec_replace, and custom exectors?

A tip: When using presenterm in my own videos, I oversample all images and diagrams until they look perfect at 4k using this in my ~.config/presenterm/config.yaml:

typst:
  # the pixels per inch when rendering latex/typst formulas.
  ppi: 300

mermaid:
  # the scale parameter passed to the mermaid CLI (mmdc).
  scale: 4

0atman avatar Jun 18 '25 10:06 0atman

What about adding support for making such a code block return a png instead?

This is already supported, see +image docs. Sorry, I saw this but never got back to it.

mfontanini avatar Jun 19 '25 00:06 mfontanini