-
Notifications
You must be signed in to change notification settings - Fork 0
Images and drawing
The image tools turn PNG, JPEG, or the first frame of a GIF into skribbl drawing commands. Install the images extra for the Python API, or cli for both the API and command-line tools.
from asyncio import run
from skribblpy.images import generate_image, render_preview
async def main() -> None:
image = await generate_image('photo.png', preset='optimized')
await image.save('drawing.json')
preview = await render_preview(image)
await preview.save('preview.png')
if __name__ == '__main__':
run(main())The JSON stores commands and image metadata. The PNG is a local preview. Rendering uses an integer approximation, so browser antialiasing may look a little different.
| Preset | What it does |
|---|---|
cluster-dot |
The default. Converts colors and compresses them into brush runs. |
yliluoma-1 |
Uses ordered dithering for intermediate tones, often with more commands. |
optimized |
Compares rendered region, stripe, and dither plans under an optional budget. |
The optimizer compares visual error, then drawing event bytes and command count to break ties. PNG or source file size doesn't drive that choice. It's the JSON sent to the server that matters.
Both limits default to None, meaning unlimited within the 100,000-command ceiling. To set them explicitly:
image = await generate_image(
'photo.png',
preset='optimized',
max_commands=4000,
max_duration=15.0,
)Use either limit or both. When you supply both, both apply. Budgets require preset='optimized'; the other presets reject them. A duration budget measures pacing delays, not network or server latency. It doesn't guarantee the server will finish displaying the drawing within that time.
To inspect the alternatives, call await optimize_image(...) from skribblpy.images. Its result includes the selected image, the selected plan name, and candidate quality scores, event payload sizes, command counts, and budget eligibility. await drawing_payload_bytes(image) measures paced DRAW event JSON, excluding the clear event and WebSocket/TLS framing.
Inside your application, once the client is the active drawer:
await client.send_image(image)This clears the canvas and sends paced batches. send_drawing(commands) plays commands without clearing. Playback uses up to eight commands per batch with 33 ms between batches, and stops with ActionError if the drawing turn changes. Keep one playback active per client.
For manual commands, use DrawCommand.brush and DrawCommand.fill. PALETTE, CANVAS_WIDTH, and CANVAS_HEIGHT are exported from skribblpy. undo_drawing(retained) keeps the first retained commands; the argument is the count to keep.
await render_preview(image) returns an immutable RasterImage. Common operations are:
| Operation | Result |
|---|---|
await RasterImage.load(path) |
Decode a source image. |
await ImageData.load(path) |
Load and validate saved drawing JSON. |
await raster.to_rgb() |
Composite transparency over white and return RGB pixels. |
await raster.to_png() |
Encode PNG bytes. |
await raster.save(path) |
Write a PNG preview. |
Conversion, rendering, encoding, metrics, and file operations run off the event loop. Reading pixels, size, tobytes(), or getpixel() stays synchronous. getpixel() expects an RGB buffer, so call to_rgb() first for other modes.
Cancelling an image operation stops waiting for it. A worker or file write that's already running may still finish.
Run these in your environment on Windows:
.venv\Scripts\python.exe -m skribblpy.cli generate --input photo.png --output drawing.json --preset optimized
.venv\Scripts\python.exe -m skribblpy.cli generate --input photo.png --output drawing.json --preset optimized --max-commands 4000
.venv\Scripts\python.exe -m skribblpy.cli preview --input drawing.json --output preview.png
.venv\Scripts\python.exe -m skribblpy.cli generate --helpOn Linux and macOS, use .venv/bin/python. The installed skribbl-image command exposes the same options when your environment is active.
preview accepts a source image or saved drawing JSON. Budget options apply to source images; they don't rewrite a saved drawing.