Scene¶
Everything starts with a Scene. Three constructors cover all use cases: Scene(w, h) for freeform art, Scene.from_image() for image-based art, and Scene.with_grid() for grid-based art without an image.
See also
For a hands-on walkthrough, see Scenes and Grids.
Scene ¶
Bases: Surface
The main container for all drawable objects in PyFreeform.
A Scene holds entities, grids, and connections. It manages rendering to SVG and provides the primary API for creating artwork.
Creating Scenes
From an image (recommended for image-based art)¶
scene = Scene.from_image("photo.jpg", grid_size=40)
With an empty grid¶
scene = Scene.with_grid(cols=30, rows=30, cell_size=12)
Manual (for non-grid art)¶
scene = Scene(800, 600, background="#fafafa")
Working with the Grid
Attributes:
| Name | Type | Description |
|---|---|---|
width |
float
|
Scene width in pixels |
height |
float
|
Scene height in pixels |
background |
str | None
|
Background color (or None for transparent) |
grid |
Grid
|
The primary grid (if created with from_image or with_grid) |
Create a new empty scene.
For image-based art, use Scene.from_image() instead. For grid-based art, use Scene.with_grid() instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
int
|
Scene width in pixels. |
required |
height
|
int
|
Scene height in pixels. |
required |
background
|
str | tuple[int, int, int] | None
|
Background color (None for transparent). |
None
|
grid
property
¶
grid: Grid
The primary grid (created by from_image or with_grid).
Index by row then column, iterate for all cells:
scene.grid[row][col]— single cellscene.grid[row]— list of cells in that rowfor cell in scene.grid:— all cells, row by row
Raises:
| Type | Description |
|---|---|
ValueError
|
If scene was created without a grid. |
connections
property
¶
connections: list[Connection]
All connections in the scene (auto-collected from entities and surfaces).
from_image
classmethod
¶
from_image(source: str | Path | Image, *, grid_size: int | None = 40, cell_size: int = 10, cell_ratio: float = 1.0, cell_width: float | None = None, cell_height: float | None = None, background: str | None = None) -> Scene
Create a scene from an image file (one-liner for image-based art).
This is the recommended way to create image-based artwork:
scene = Scene.from_image("photo.jpg", grid_size=40)
for cell in scene.grid:
cell.add_dot(color=cell.color)
scene.save("art.svg")
Two modes
- grid_size=N (default): N columns, auto rows from aspect ratio. Scene size = cols * cell_size x rows * cell_size.
- grid_size=None: Grid fits the image. Cols/rows derived from image dimensions ÷ cell size. Scene size ≈ image dimensions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str | Path | Image
|
Path to image file, or an Image object. |
required |
grid_size
|
int | None
|
Number of columns (rows auto-calculated from aspect ratio). Pass None to derive grid from image dimensions. |
40
|
cell_size
|
int
|
Base size of each cell in pixels. |
10
|
cell_ratio
|
float
|
Width-to-height ratio (e.g., 2.0 for domino cells). |
1.0
|
cell_width
|
float | None
|
Explicit cell width (overrides cell_size and cell_ratio). |
None
|
cell_height
|
float | None
|
Explicit cell height (overrides cell_size). |
None
|
background
|
str | None
|
Background color (defaults to dark blue). |
None
|
Returns:
| Type | Description |
|---|---|
Scene
|
Scene with grid loaded from image, ready to iterate. |
The grid's cells will have typed properties: - cell.color: Hex color string - cell.brightness: Float 0.0-1.0 - cell.rgb: Tuple (r, g, b) - cell.alpha: Float 0.0-1.0
with_grid
classmethod
¶
with_grid(*, cols: int = 30, rows: int | None = None, cell_size: int = 10, cell_width: float | None = None, cell_height: float | None = None, background: str | None = None) -> Scene
Create a scene with an empty grid (for non-image-based art).
scene = Scene.with_grid(cols=30, rows=30, cell_size=12)
for cell in scene.grid:
cell.add_dot(color="coral")
scene.save("art.svg")
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cols
|
int
|
Number of columns. |
30
|
rows
|
int | None
|
Number of rows (defaults to same as cols for square grid). |
None
|
cell_size
|
int
|
Base size of each cell in pixels. |
10
|
cell_width
|
float | None
|
Explicit cell width (overrides cell_size). |
None
|
cell_height
|
float | None
|
Explicit cell height (overrides cell_size). |
None
|
background
|
str | None
|
Background color. |
None
|
Returns:
| Type | Description |
|---|---|
Scene
|
Scene with empty grid, ready to iterate. |
add_grid ¶
remove ¶
remove(entity: Entity) -> bool
Remove an entity from the scene.
Searches both direct entities and grid cells.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entity
|
Entity
|
The entity to remove. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if entity was found and removed. |
remove_grid ¶
remove_grid(grid: Grid) -> bool
Remove a grid from the scene.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid
|
Grid
|
The grid to remove. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if grid was found and removed. |
to_svg ¶
Render the scene to an SVG string.
Entities and connections are sorted by z_index before rendering. Lower z_index values render first (underneath). Higher z_index values render last (on top).
Returns:
| Type | Description |
|---|---|
str
|
Complete SVG document as string. |
save ¶
Save the scene to an SVG file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
File path (will add .svg extension if missing). |
required |
renderer
|
Optional Renderer instance. Defaults to SMILRenderer. |
None
|
crop ¶
crop(padding: float = 0) -> Scene
Crop the scene viewBox to fit the visual bounds of all content.
Useful for transparent exports (icons, badges) where you don't want dead space around the artwork.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
padding
|
float
|
Extra space around the content in pixels. |
0
|
Returns:
| Type | Description |
|---|---|
Scene
|
self, for method chaining. |
trim ¶
trim(top: float = 0, right: float = 0, bottom: float = 0, left: float = 0) -> Scene
Remove pixels from one or more edges of the scene.
Adjusts the viewBox so the specified number of pixels are clipped
from each side. Can be chained with :meth:crop.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
top
|
float
|
Pixels to remove from the top edge. |
0
|
right
|
float
|
Pixels to remove from the right edge. |
0
|
bottom
|
float
|
Pixels to remove from the bottom edge. |
0
|
left
|
float
|
Pixels to remove from the left edge. |
0
|
Returns:
| Type | Description |
|---|---|
Scene
|
self, for method chaining. |