-
-
Notifications
You must be signed in to change notification settings - Fork 659
Lua: Image Rendering
Conky can display images through two libraries:
- Imlib2 — for raster images (PNG, JPEG, BMP, etc.)
- RSVG — for SVG vector graphics
Both are optional and may not be available depending on how Conky was built.
See Using Lua Scripts for general setup.
Warning
Like Cairo, image library bindings must be loaded with require() and any
handles or images must be freed after use to avoid
resource leaks. Since draw
hooks run every update, a missing cleanup call will cause Conky to consume
more and more memory over time. This will be especially noticable with images
as they're much larger than most other resources.
Imlib2 is an image loading and rendering library. Conky exposes its API through Lua bindings that are nearly identical to the C API.
require("imlib2")The basic workflow is: load an image, set it as the current context image, render it onto the Conky drawable, then free it.
Important
Imlib2 renders directly to X11 drawables — it requires conky_window fields
that are X11-specific and does not work on Wayland. For cross-platform
image rendering, use cairo_place_image() from the
Cairo integration helper instead.
require("imlib2")
function conky_main()
if conky_window == nil then return end
-- Set up Imlib2 to draw on the Conky window (X11 only)
imlib_context_set_display(conky_window.display)
imlib_context_set_visual(conky_window.visual)
imlib_context_set_colormap(conky_window.colormap)
imlib_context_set_drawable(conky_window.drawable)
-- Load and render an image
local image = imlib_load_image("/path/to/image.png")
if image then
imlib_context_set_image(image)
imlib_render_image_on_drawable(10, 10)
imlib_free_image()
end
endTo render at a different size, use
imlib_render_image_on_drawable_at_size():
local image = imlib_load_image("/path/to/icon.png")
if image then
imlib_context_set_image(image)
imlib_render_image_on_drawable_at_size(10, 10, 64, 64)
imlib_free_image()
endTo render a portion of an image, create a cropped and scaled copy:
local image = imlib_load_image("/path/to/image.png")
if image then
imlib_context_set_image(image)
-- Crop a 100x100 region from (50, 50) and scale it to 200x200
local cropped = imlib_create_cropped_scaled_image(50, 50, 100, 100, 200, 200)
imlib_free_image() -- free the original
imlib_context_set_image(cropped)
imlib_render_image_on_drawable(10, 10)
imlib_free_image() -- free the cropped copy
endConky provides a convenience function that combines Imlib2 image loading with Cairo rendering:
require("cairo_imlib2_helper")
-- Draw an image onto a Cairo surface with optional scaling
cairo_place_image("/path/to/image.png", cr, 10, 10, 64, 64, 1.0)
-- Arguments: filename, cairo context, x, y, width, height, alphaThis is simpler than using the Imlib2 API directly when you're already working with Cairo.
local image = imlib_load_image("/path/to/image.png")
if image then
imlib_context_set_image(image)
local w = imlib_image_get_width()
local h = imlib_image_get_height()
-- use w, h for layout calculations
imlib_free_image()
endTip
If you're loading the same image every update cycle, consider caching the
loaded image in a global variable and only reloading when necessary (e.g. on
a timer). imlib_load_image() does use an internal cache, but skipping the
call entirely is still faster.
RSVG renders SVG vector graphics onto Cairo surfaces. Because SVGs are resolution-independent, they scale cleanly to any size.
require("rsvg")The workflow is: create a handle from a file, set up a viewport rectangle that defines where and how large the SVG should be drawn, render it onto a Cairo context, then clean up.
require("cairo")
require("rsvg")
function conky_main()
local surface = conky_surface()
if not surface then return end
local cr = cairo_create(surface)
-- Load the SVG
local handle = rsvg_create_handle_from_file("/path/to/image.svg")
if handle then
-- Define the viewport (position and size)
local viewport = RsvgRectangle:create()
viewport:set(10, 10, 200, 200)
-- Render onto the Cairo context
rsvg_handle_render_document(handle, cr, viewport)
-- Cleanup
viewport:destroy()
rsvg_destroy_handle(handle)
end
cairo_destroy(cr)
endUse
cairo_translate()
to position the SVG independently of the viewport origin:
cairo_save(cr)
cairo_translate(cr, 50, 100) -- offset the SVG
local viewport = RsvgRectangle:create()
viewport:set(0, 0, 200, 200) -- viewport at translated origin
rsvg_handle_render_document(handle, cr, viewport)
viewport:destroy()
cairo_restore(cr)To get the intrinsic size of an SVG (the size defined in the file):
local handle = rsvg_create_handle_from_file("/path/to/image.svg")
if handle then
local has_size, w, h = rsvg_handle_get_intrinsic_size_in_pixels(handle)
if has_size then
-- use w, h for layout
end
rsvg_destroy_handle(handle)
endSVG files can contain named elements (via id attributes). To render only a
specific element:
if rsvg_handle_has_sub(handle, "#layer1") then
local viewport = RsvgRectangle:create()
viewport:set(0, 0, 200, 200)
rsvg_handle_render_layer(handle, cr, "#layer1", viewport)
viewport:destroy()
end- Imlib2 API Reference — full C API documentation (Lua bindings mirror these functions)
- RSVG API Reference — librsvg documentation
- Drawing with Cairo — Cairo drawing fundamentals used alongside image rendering