geomotif.io.png
¶
Write a PNG still, in pure standard library.
A still is the finished drawing one more time: where the GIF is a moving
picture, a PNG is a picture that does not move, and this module is its
release form. It renders a design once -- as a full-color, palette-free
frame, antialiased or hard-edged on request -- and then encodes that frame
with nothing but the standard library: the rows are filtered, zlib
compresses them, and every chunk gets its CRC-32, which is the whole of
the PNG file format.
The writer answers to the same styling vocabulary as the GIF writer
(ink, background, thickness, padding, antialias), so a
design that looks right as a GIF looks the same way as a PNG. Unlike the
GIF it keeps every color it was drawn in, because a PNG has no 256-color
budget::
from geomotif.io.png import save_png
from geomotif.motifs import Rose
save_png(Rose(n=7).build(), "rose.png")
It can write three ways, chosen by color:
"rgb"(the default) -- truecolor, three bytes a pixel. Lossless and full color; the picture to reach for by default."rgba"-- truecolor with an alpha channel, four bytes a pixel. Withtransparentit leaves the background empty; without, the alpha is opaque."indexed"-- a palette of at most 256 colors, one byte a pixel. The smallest files, at the cost of a palette; the same median-cut quantizer the GIF uses shrinks the frame down, with optional dithering.
Functions:
| Name | Description |
|---|---|
to_png |
Render a design -- or re-encode a :class: |
save_png |
Render a design -- or re-encode a raster -- as a PNG and write it. |
to_png
¶
to_png(source: Design | Raster, *, width: int = 480, height: int = 480, padding: float = 8.0, ink: str = '#0b0b0b', background: str = '#ffffff', thickness: int = 1, dot_radius: int | None = None, antialias: bool = False, aa_level: int = 8, color: str = 'rgb', compression: int = 6, transparent: bool = False) -> bytes
Render a design -- or re-encode a :class:~geomotif.io.Raster -- as PNG.
A still is drawn once, exactly the way :func:to_gif draws a frame, and
then written as a PNG instead of being quantized toward a GIF's colors.
The styling parameters are shared with the GIF writer so one summoning
controls both.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Design or Raster
|
What to write. A design is drawn; a raster is encoded as it is. |
required |
width
|
int
|
Canvas size in pixels. Ignored when |
480
|
height
|
int
|
Canvas size in pixels. Ignored when |
480
|
padding
|
float
|
Margin reserved on all four sides, in pixels. |
8.0
|
ink
|
str
|
Default stroke color and the color behind everything. |
'#0b0b0b'
|
background
|
str
|
Default stroke color and the color behind everything. |
'#0b0b0b'
|
thickness
|
int
|
Stroke width in pixels. |
1
|
dot_radius
|
int
|
Radius for loose points. Defaults to |
None
|
antialias
|
bool
|
Supersample and blend edges. Off by default, so the edges are the same hard Bresenham edges they have always been. |
False
|
aa_level
|
int
|
When antialiasing into an indexed frame, how many shades an edge may blend into per color pair. Ignored for the truecolor paths, which keep every level. |
8
|
color
|
str
|
|
'rgb'
|
compression
|
int
|
zlib level from 0 (fast, big) to 9 (slow, small). Must be an integer in that range. |
6
|
transparent
|
bool
|
Leave the background empty instead of painting |
False
|
Returns:
| Type | Description |
|---|---|
bytes
|
A complete PNG file. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/geomotif/io/png.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | |
save_png
¶
Render a design -- or re-encode a raster -- as a PNG and write it.
Keyword arguments are passed straight through to :func:to_png.