0
# PNG Writing Operations
1
2
Comprehensive PNG encoding capabilities with full format control, metadata support, and optimization options. The Writer class handles all PNG color types, bit depths, and optional chunks for professional-quality PNG creation.
3
4
## Capabilities
5
6
### PNG File Writing
7
8
The Writer class provides complete control over PNG creation with extensive format and metadata options.
9
10
```python { .api }
11
class Writer:
12
def __init__(self, width=None, height=None, size=None, greyscale=Default,
13
alpha=False, bitdepth=8, palette=None, transparent=None,
14
background=None, gamma=None, compression=None, interlace=False,
15
planes=None, colormap=None, maxval=None, chunk_limit=2**20,
16
x_pixels_per_unit=None, y_pixels_per_unit=None, unit_is_meter=False):
17
"""
18
Initialize PNG writer with format and metadata options.
19
20
Parameters:
21
- width, height: int, image dimensions in pixels
22
- size: tuple, alternative way to specify (width, height)
23
- greyscale: bool or Default, whether to create greyscale image
24
- alpha: bool, whether to include alpha channel
25
- bitdepth: int, bits per sample (1, 2, 4, 8, 16)
26
- palette: list, RGB or RGBA tuples for palette images
27
- transparent: color value or index for transparency
28
- background: color value for default background
29
- gamma: float, gamma correction value
30
- compression: int, zlib compression level (0-9)
31
- interlace: bool, whether to use Adam7 interlacing
32
- planes: int, deprecated, use greyscale and alpha instead
33
- colormap: dict, deprecated, use palette instead
34
- maxval: int, maximum pixel value for scaling
35
- chunk_limit: int, maximum chunk size in bytes
36
- x_pixels_per_unit, y_pixels_per_unit: int, resolution information
37
- unit_is_meter: bool, whether resolution units are meters (vs. unknown)
38
"""
39
```
40
41
### Writing Methods
42
43
Multiple methods for writing PNG data from different Python data structures.
44
45
```python { .api }
46
def write(self, outfile, rows):
47
"""
48
Write PNG from row iterator.
49
50
Parameters:
51
- outfile: file-like object opened in binary write mode
52
- rows: iterable of pixel rows, each row is sequence of pixel values
53
"""
54
55
def write_array(self, outfile, pixels):
56
"""
57
Write PNG from 2D array or nested sequences.
58
59
Parameters:
60
- outfile: file-like object opened in binary write mode
61
- pixels: 2D array-like structure of pixel data
62
"""
63
64
def write_packed(self, outfile, rows):
65
"""
66
Write PNG from pre-packed byte rows.
67
68
Parameters:
69
- outfile: file-like object opened in binary write mode
70
- rows: iterable of byte strings representing packed pixel rows
71
"""
72
73
def write_passes(self, outfile, rows):
74
"""
75
Write PNG with interlacing support.
76
77
Parameters:
78
- outfile: file-like object opened in binary write mode
79
- rows: iterable of pixel rows for interlaced writing
80
"""
81
```
82
83
## Usage Examples
84
85
### Basic PNG Writing
86
87
```python
88
import png
89
90
# Create a simple RGB image
91
width, height = 256, 256
92
pixels = []
93
94
# Generate gradient pattern
95
for y in range(height):
96
row = []
97
for x in range(width):
98
# RGB gradient
99
r = (x * 255) // width
100
g = (y * 255) // height
101
b = 128
102
row.extend([r, g, b])
103
pixels.append(row)
104
105
# Write PNG
106
writer = png.Writer(width=width, height=height, greyscale=False)
107
with open('gradient.png', 'wb') as f:
108
writer.write_array(f, pixels)
109
```
110
111
### Greyscale Image Writing
112
113
```python
114
import png
115
116
# Create greyscale image
117
width, height = 100, 100
118
pixels = []
119
120
for y in range(height):
121
row = []
122
for x in range(width):
123
# Simple checkerboard pattern
124
if (x // 10 + y // 10) % 2:
125
grey = 255 # White
126
else:
127
grey = 0 # Black
128
row.append(grey)
129
pixels.append(row)
130
131
# Write greyscale PNG
132
writer = png.Writer(width=width, height=height, greyscale=True, bitdepth=8)
133
with open('checkerboard.png', 'wb') as f:
134
writer.write_array(f, pixels)
135
```
136
137
### RGBA Image with Transparency
138
139
```python
140
import png
141
142
# Create RGBA image with transparency
143
width, height = 64, 64
144
pixels = []
145
146
for y in range(height):
147
row = []
148
for x in range(width):
149
# Create a circle with alpha blending
150
center_x, center_y = width // 2, height // 2
151
distance = ((x - center_x) ** 2 + (y - center_y) ** 2) ** 0.5
152
153
if distance < width // 3:
154
# Inside circle - solid color
155
r, g, b, a = 255, 100, 50, 255
156
elif distance < width // 2:
157
# Edge of circle - fade out
158
alpha = int(255 * (1 - (distance - width//3) / (width//2 - width//3)))
159
r, g, b, a = 255, 100, 50, alpha
160
else:
161
# Outside circle - transparent
162
r, g, b, a = 0, 0, 0, 0
163
164
row.extend([r, g, b, a])
165
pixels.append(row)
166
167
# Write RGBA PNG
168
writer = png.Writer(width=width, height=height, greyscale=False, alpha=True)
169
with open('circle_alpha.png', 'wb') as f:
170
writer.write_array(f, pixels)
171
```
172
173
### Palette-Based Image
174
175
```python
176
import png
177
178
# Define color palette
179
palette = [
180
(255, 0, 0), # Red
181
(0, 255, 0), # Green
182
(0, 0, 255), # Blue
183
(255, 255, 0), # Yellow
184
(255, 0, 255), # Magenta
185
(0, 255, 255), # Cyan
186
(255, 255, 255), # White
187
(0, 0, 0) # Black
188
]
189
190
# Create image using palette indices
191
width, height = 32, 32
192
pixels = []
193
194
for y in range(height):
195
row = []
196
for x in range(width):
197
# Use palette index based on position
198
palette_index = (x // 4 + y // 4) % len(palette)
199
row.append(palette_index)
200
pixels.append(row)
201
202
# Write palette PNG
203
writer = png.Writer(width=width, height=height, palette=palette, bitdepth=8)
204
with open('palette_image.png', 'wb') as f:
205
writer.write_array(f, pixels)
206
```
207
208
### High Bit Depth Images
209
210
```python
211
import png
212
213
# Create 16-bit per channel image
214
width, height = 64, 64
215
pixels = []
216
217
for y in range(height):
218
row = []
219
for x in range(width):
220
# Use full 16-bit range (0-65535)
221
r = (x * 65535) // width
222
g = (y * 65535) // height
223
b = 32768 # Mid-range value
224
row.extend([r, g, b])
225
pixels.append(row)
226
227
# Write 16-bit RGB PNG
228
writer = png.Writer(width=width, height=height, greyscale=False, bitdepth=16)
229
with open('high_bit_depth.png', 'wb') as f:
230
writer.write_array(f, pixels)
231
```
232
233
### PNG with Metadata
234
235
```python
236
import png
237
238
# Create simple image
239
width, height = 32, 32
240
pixels = [[y * 8 for x in range(width)] for y in range(height)]
241
242
# Write PNG with gamma correction and resolution metadata
243
writer = png.Writer(
244
width=width,
245
height=height,
246
greyscale=True,
247
gamma=2.2, # Gamma correction
248
x_pixels_per_unit=2835, # 72 DPI in pixels per meter
249
y_pixels_per_unit=2835,
250
unit_is_meter=True
251
)
252
253
with open('metadata_image.png', 'wb') as f:
254
writer.write_array(f, pixels)
255
```
256
257
### Row-by-Row Writing
258
259
```python
260
import png
261
262
def generate_rows(width, height):
263
"""Generator function that yields rows on demand"""
264
for y in range(height):
265
row = []
266
for x in range(width):
267
# Generate pixel data on-the-fly
268
value = (x + y) % 256
269
row.append(value)
270
yield row
271
272
# Write PNG using row generator (memory efficient for large images)
273
width, height = 1000, 1000
274
writer = png.Writer(width=width, height=height, greyscale=True)
275
276
with open('large_generated.png', 'wb') as f:
277
writer.write(f, generate_rows(width, height))
278
```