r/django • u/blopker1 • 12h ago
Releases Dynimg - Dynamic images from HTML
Hey everyone, I just put out version 0.2.0 of Dynimg. It's a Python/Rust package that takes in HTML/CSS and outputs high quality images. If you've ever had to deal with generating images for blog posts (for OG/preview images etc), you know the options are either to run a full headless browser, or build a complicated Pillow pipeline.
I've been making Django apps since version 0.96 (I'm old, sorry), and this is a problem I've needed a solution for many times. It's now finally possible because of another project called Blitz, which is a modular browser built in Rust.
Dynimg is a focused wrapper around parts of Blitz designed around just turning custom HTML and CSS into crisp static images. It's very fast (~20ms) compared to using a full browser to do the same thing. While there's no Django-specific integrations, it works well with Django templates using render_to_string as input.
Example Django code:
import dynimg
html = render_to_string("og.html", ctx)
dynimg.render(html).save_png("og.png")
We've been using Dynimg in production with Django at totem.org for a while now, and it's been just chugging along without issue, so I thought I'd share it here in case anyone else finds it useful.
Despite not being version 1 yet, it is largely feature complete. The main issue is Blitz is still early and there will be slight rendering differences as it matures. However, if you pin Dynimg your images stay stable.
It supports external and local assets (images, CSS, fonts, etc). It works well with Google Fonts for example. Comes with a CLI, Python API and Rust API. It supports PNG, JPEG, and WebP outputs.
Limitations:
- This is not designed to take arbitrary HTML from websites to make screenshots. It is for turning small custom templates into images quickly.
- It's designed to be secure (network and filesystem access are off by default), but it's not designed to take arbitrary user-submitted documents. If you want to use it this way and you find a security flaw, let me know in the repo.
- It does not support JavaScript.
- It does not support every CSS/HTML feature (though more support is added all the time), so make sure to verify it's doing what you want. You may need hacks to get images rendering like a real browser.
- The output images are reasonably sized, but the encoding options are geared for quality. You may want to use a library to fully optimize the image for your use case, then cache it for production.
We currently use it to make dynamic OG and social media images. We host a secret URL on Django for staff to use images how they want: example. You can see example templates here, with how they render here.
Let me know if you like it!