0
# Image Container Operations
1
2
The Image class provides a convenient container for PNG image data with automatic format handling and multiple output methods. It bridges PNG reading and writing operations with a simple, high-level interface.
3
4
## Capabilities
5
6
### Image Container Class
7
8
The Image class encapsulates PNG image data and metadata, providing convenient methods for saving and manipulating image data.
9
10
```python { .api }
11
class Image:
12
def __init__(self, rows, info):
13
"""
14
Initialize Image container with pixel data and metadata.
15
16
Parameters:
17
- rows: iterable of pixel rows
18
- info: dict containing PNG metadata (width, height, bitdepth, etc.)
19
20
Note: This constructor is not intended for direct use. Create Image
21
objects using png.from_array() or Reader methods that return Images.
22
"""
23
24
def save(self, file):
25
"""
26
Save image to a named file.
27
28
Parameters:
29
- file: str, path to output PNG file
30
"""
31
32
def write(self, file):
33
"""
34
Write image to an open file object.
35
36
Parameters:
37
- file: file-like object opened in binary write mode
38
"""
39
40
def stream(self):
41
"""
42
Convert row iterator to accessible list.
43
44
Returns:
45
list: List of pixel rows, where each row is a sequence of pixel values
46
47
Note: This method consumes the row iterator, so it can only be called once.
48
"""
49
```
50
51
## Usage Examples
52
53
### Creating Images from Arrays
54
55
```python
56
import png
57
58
# Create Image from 2D array
59
pixel_data = [
60
[255, 0, 0, 255, 255, 0], # Red, Yellow pixels (RGB)
61
[0, 255, 0, 0, 0, 255], # Green, Blue pixels
62
[128, 128, 128, 64, 64, 64] # Two grey pixels
63
]
64
65
# Create Image object
66
image = png.from_array(pixel_data, 'RGB')
67
68
# Save to file
69
image.save('array_image.png')
70
```
71
72
### Working with Image Data
73
74
```python
75
import png
76
77
# Create a simple greyscale gradient
78
width, height = 64, 64
79
pixels = []
80
for y in range(height):
81
row = []
82
for x in range(width):
83
# Diagonal gradient
84
value = int(255 * (x + y) / (width + height - 2))
85
row.append(value)
86
pixels.append(row)
87
88
# Create Image
89
image = png.from_array(pixels, 'L') # 'L' for greyscale
90
91
# Access pixel data as list
92
pixel_rows = image.stream()
93
print(f"Image has {len(pixel_rows)} rows")
94
print(f"First row has {len(pixel_rows[0])} pixels")
95
print(f"Top-left pixel value: {pixel_rows[0][0]}")
96
print(f"Bottom-right pixel value: {pixel_rows[-1][-1]}")
97
```
98
99
### Converting Between Formats
100
101
```python
102
import png
103
104
# Read existing PNG as Image
105
reader = png.Reader(filename='input.png')
106
width, height, rows, info = reader.read()
107
108
# Create Image container
109
image = png.Image(rows, info)
110
111
# Save with different filename
112
image.save('copy.png')
113
114
# Or write to file object with custom handling
115
with open('processed.png', 'wb') as f:
116
image.write(f)
117
```
118
119
### Processing Image Data
120
121
```python
122
import png
123
124
# Create test image
125
original_data = [
126
[100, 150, 200], # Row 1
127
[120, 170, 220], # Row 2
128
[140, 190, 240] # Row 3
129
]
130
131
image = png.from_array(original_data, 'L')
132
133
# Get pixel data for processing
134
rows = image.stream()
135
136
# Process pixels (brighten by 20%)
137
processed_rows = []
138
for row in rows:
139
new_row = []
140
for pixel in row:
141
# Brighten pixel, clamp to 255
142
new_pixel = min(255, int(pixel * 1.2))
143
new_row.append(new_pixel)
144
processed_rows.append(new_row)
145
146
# Create new image with processed data
147
processed_image = png.from_array(processed_rows, 'L')
148
processed_image.save('brightened.png')
149
```
150
151
### Memory-Efficient Image Handling
152
153
```python
154
import png
155
156
def process_large_image(input_file, output_file):
157
"""Process large PNG file without loading entire image into memory"""
158
159
# Read image metadata without loading all pixel data
160
reader = png.Reader(filename=input_file)
161
width, height, rows, info = reader.read()
162
163
# Process rows one at a time
164
def processed_rows():
165
for row in rows:
166
# Apply some processing to each row
167
processed_row = [min(255, pixel + 50) for pixel in row]
168
yield processed_row
169
170
# Write processed image
171
writer = png.Writer(width=width, height=height, **info)
172
with open(output_file, 'wb') as f:
173
writer.write(f, processed_rows())
174
175
# Usage
176
process_large_image('large_input.png', 'large_output.png')
177
```
178
179
### Image Information Access
180
181
```python
182
import png
183
184
# Create image with metadata
185
pixels = [[x for x in range(100)] for y in range(50)]
186
image = png.from_array(pixels, 'L')
187
188
# The Image object contains the info dict with metadata
189
# Access through the internal structure (for advanced use)
190
print("Image dimensions available through save/write operations")
191
192
# To access metadata, work with Reader directly
193
reader = png.Reader(filename='test.png')
194
width, height, rows, info = reader.read()
195
196
print(f"Width: {width}")
197
print(f"Height: {height}")
198
print(f"Bit depth: {info.get('bitdepth', 'unknown')}")
199
print(f"Color type: {info.get('greyscale', 'color')}")
200
print(f"Has alpha: {info.get('alpha', False)}")
201
print(f"Interlaced: {info.get('interlace', False)}")
202
```
203
204
### Chaining Operations
205
206
```python
207
import png
208
209
# Chain Image operations for fluent workflow
210
def create_test_pattern():
211
"""Create a test pattern image"""
212
width, height = 32, 32
213
pixels = []
214
215
for y in range(height):
216
row = []
217
for x in range(width):
218
# Create checkerboard pattern
219
if (x // 4 + y // 4) % 2:
220
r, g, b = 255, 255, 255 # White
221
else:
222
r, g, b = 0, 0, 0 # Black
223
row.extend([r, g, b])
224
pixels.append(row)
225
226
return png.from_array(pixels, 'RGB')
227
228
# Create and save in one operation
229
test_image = create_test_pattern()
230
test_image.save('test_pattern.png')
231
232
# Or use for further processing
233
pixel_data = test_image.stream()
234
print(f"Created {len(pixel_data)}x{len(pixel_data[0])//3} RGB image")
235
```