0
# Encoding
1
2
Functions for creating HEIF/AVIF files from raw data, Pillow images, or other sources. These functions provide comprehensive encoding capabilities with quality control, format selection, and advanced compression options.
3
4
## Capabilities
5
6
### Direct Encoding from Raw Data
7
8
Encodes raw image data directly to a HEIF/AVIF file with full control over encoding parameters.
9
10
```python { .api }
11
def encode(mode: str, size: tuple[int, int], data: bytes, fp, **kwargs) -> None:
12
"""
13
Encode raw image data to HEIF/AVIF format.
14
15
Parameters:
16
- mode: str, color mode ('RGB', 'RGBA', 'L', etc.)
17
- size: tuple[int, int], image dimensions (width, height)
18
- data: bytes, raw image data
19
- fp: output file path or file-like object
20
- **kwargs: encoding options
21
22
Encoding Options:
23
- quality: int, compression quality 0-100 (default: 50)
24
- format: str, output format 'HEIF' or 'AVIF' (auto-detected from extension)
25
- compression_format: str, specific compression format
26
- lossless: bool, enable lossless compression
27
- effort: int, encoding effort 0-9 for AVIF (higher = smaller file)
28
- chroma_subsampling: str, chroma subsampling mode
29
- save_all: bool, save all provided images
30
31
Raises:
32
IOError: If encoding fails or parameters are invalid
33
"""
34
```
35
36
Usage example:
37
```python
38
import pillow_heif
39
import numpy as np
40
41
# Create sample RGB data
42
width, height = 640, 480
43
rgb_data = np.random.randint(0, 255, (height, width, 3), dtype=np.uint8)
44
45
# Encode to HEIF
46
pillow_heif.encode(
47
mode="RGB",
48
size=(width, height),
49
data=rgb_data.tobytes(),
50
fp="encoded_image.heic",
51
quality=90
52
)
53
54
# Encode to AVIF with high effort
55
pillow_heif.encode(
56
mode="RGB",
57
size=(width, height),
58
data=rgb_data.tobytes(),
59
fp="encoded_image.avif",
60
quality=80,
61
effort=9
62
)
63
```
64
65
### Creating HeifFile from Pillow Images
66
67
Converts Pillow Image objects to HeifFile containers, preserving metadata and supporting various Pillow image modes.
68
69
```python { .api }
70
def from_pillow(pil_image: 'PIL.Image.Image') -> HeifFile:
71
"""
72
Create HeifFile from Pillow Image.
73
74
Parameters:
75
- pil_image: PIL.Image, source Pillow image
76
77
Returns:
78
HeifFile: Container with converted image data
79
80
Notes:
81
- Preserves image metadata (EXIF, etc.) when present
82
- Supports all Pillow color modes
83
- Handles transparency in RGBA images
84
"""
85
```
86
87
Usage example:
88
```python
89
import pillow_heif
90
from PIL import Image
91
92
# Create or load Pillow image
93
pil_image = Image.open("source.jpg")
94
pil_image = pil_image.convert("RGB")
95
96
# Convert to HeifFile
97
heif_file = pillow_heif.from_pillow(pil_image)
98
99
# Save with specific quality
100
heif_file.save("converted.heic", quality=85)
101
102
# Work with transparency
103
rgba_image = Image.open("transparent.png").convert("RGBA")
104
heif_file = pillow_heif.from_pillow(rgba_image)
105
heif_file.save("transparent.heic", quality=90)
106
```
107
108
### Creating HeifFile from Raw Bytes
109
110
Creates HeifFile containers from raw image data with specified format parameters.
111
112
```python { .api }
113
def from_bytes(mode: str, size: tuple[int, int], data: bytes, **kwargs) -> HeifFile:
114
"""
115
Create HeifFile from raw image bytes.
116
117
Parameters:
118
- mode: str, color mode ('RGB', 'RGBA', 'L', etc.)
119
- size: tuple[int, int], image dimensions (width, height)
120
- data: bytes, raw image data
121
- **kwargs: additional options for image creation
122
123
Additional Options:
124
- stride: int, bytes per row (calculated automatically if not provided)
125
- info: dict, metadata to attach to image
126
127
Returns:
128
HeifFile: Container with image data ready for processing or saving
129
"""
130
```
131
132
Usage example:
133
```python
134
import pillow_heif
135
import numpy as np
136
137
# Create image data
138
width, height = 400, 300
139
rgb_array = np.random.randint(0, 255, (height, width, 3), dtype=np.uint8)
140
141
# Create HeifFile from raw bytes
142
heif_file = pillow_heif.from_bytes(
143
mode="RGB",
144
size=(width, height),
145
data=rgb_array.tobytes()
146
)
147
148
# Add metadata
149
heif_file.info['description'] = "Generated test image"
150
151
# Save to file
152
heif_file.save("from_bytes.heic", quality=75)
153
154
# Create RGBA image with transparency
155
rgba_array = np.random.randint(0, 255, (height, width, 4), dtype=np.uint8)
156
rgba_array[:, :, 3] = 128 # Semi-transparent
157
158
heif_file = pillow_heif.from_bytes(
159
mode="RGBA",
160
size=(width, height),
161
data=rgba_array.tobytes()
162
)
163
heif_file.save("transparent_from_bytes.heic")
164
```
165
166
## Encoding Options and Quality Control
167
168
### Quality Settings
169
170
```python
171
import pillow_heif
172
173
# High quality (larger file)
174
heif_file.save("high_quality.heic", quality=95)
175
176
# Medium quality (balanced)
177
heif_file.save("medium_quality.heic", quality=75)
178
179
# Low quality (smaller file)
180
heif_file.save("low_quality.heic", quality=50)
181
182
# Lossless compression
183
heif_file.save("lossless.heic", lossless=True)
184
185
# Auto quality (let encoder decide)
186
heif_file.save("auto_quality.heic", quality=-1)
187
```
188
189
### Format Selection
190
191
```python
192
import pillow_heif
193
194
# Force HEIF format
195
heif_file.save("image.heic", format="HEIF")
196
197
# Force AVIF format
198
heif_file.save("image.avif", format="AVIF")
199
200
# Auto-detect from extension
201
heif_file.save("image.heic") # Uses HEIF
202
heif_file.save("image.avif") # Uses AVIF
203
```
204
205
### Advanced AVIF Options
206
207
```python
208
import pillow_heif
209
210
# High effort encoding (slower but smaller)
211
heif_file.save("high_effort.avif", effort=9, quality=80)
212
213
# Fast encoding
214
heif_file.save("fast.avif", effort=0, quality=80)
215
216
# Custom chroma subsampling
217
heif_file.save("custom_chroma.avif", chroma_subsampling="4:2:0")
218
```
219
220
### HDR and High Bit Depth Encoding
221
222
```python
223
import pillow_heif
224
import numpy as np
225
226
# Create 10-bit HDR data
227
width, height = 1920, 1080
228
hdr_data = np.random.randint(0, 1023, (height, width, 3), dtype=np.uint16)
229
230
# Encode as 10-bit HEIF
231
heif_file = pillow_heif.from_bytes(
232
mode="RGB;10",
233
size=(width, height),
234
data=hdr_data.tobytes()
235
)
236
heif_file.save("hdr_10bit.heic", quality=-1) # Preserve bit depth
237
238
# 12-bit encoding
239
pillow_heif.options.SAVE_HDR_TO_12_BIT = True
240
heif_file.save("hdr_12bit.heic", quality=-1)
241
```
242
243
## Multi-Image Encoding
244
245
### Creating Multi-Image Files
246
247
```python
248
import pillow_heif
249
from PIL import Image
250
251
# Create empty HeifFile
252
heif_file = pillow_heif.HeifFile()
253
254
# Add multiple images
255
for i in range(3):
256
pil_image = Image.new("RGB", (640, 480), color=(i*80, 0, 0))
257
heif_file.add_from_pillow(pil_image)
258
259
# Set primary image
260
heif_file.primary_index = 0
261
262
# Save multi-image file
263
heif_file.save("multi_image.heic", save_all=True, quality=85)
264
```
265
266
### Batch Processing
267
268
```python
269
import pillow_heif
270
from PIL import Image
271
import os
272
273
def batch_convert_to_heif(input_dir, output_dir, quality=80):
274
"""Convert all images in directory to HEIF format."""
275
os.makedirs(output_dir, exist_ok=True)
276
277
for filename in os.listdir(input_dir):
278
if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
279
input_path = os.path.join(input_dir, filename)
280
output_path = os.path.join(output_dir,
281
os.path.splitext(filename)[0] + '.heic')
282
283
try:
284
pil_image = Image.open(input_path)
285
heif_file = pillow_heif.from_pillow(pil_image)
286
heif_file.save(output_path, quality=quality)
287
print(f"Converted: {filename}")
288
except Exception as e:
289
print(f"Error converting {filename}: {e}")
290
291
# Usage
292
batch_convert_to_heif("input_images/", "output_heif/", quality=85)
293
```
294
295
## OpenCV Integration
296
297
### Encoding from OpenCV Arrays
298
299
```python
300
import pillow_heif
301
import cv2
302
import numpy as np
303
304
# Load image with OpenCV
305
cv_image = cv2.imread("input.jpg", cv2.IMREAD_COLOR) # BGR format
306
307
# Convert BGR to RGB for standard encoding
308
rgb_image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB)
309
310
# Create HeifFile from OpenCV array
311
heif_file = pillow_heif.from_bytes(
312
mode="RGB",
313
size=(cv_image.shape[1], cv_image.shape[0]), # width, height
314
data=rgb_image.tobytes()
315
)
316
317
# Save as HEIF
318
heif_file.save("opencv_to_heif.heic", quality=90)
319
320
# Alternative: Use BGR mode directly
321
heif_file = pillow_heif.from_bytes(
322
mode="RGB", # Still RGB mode
323
size=(cv_image.shape[1], cv_image.shape[0]),
324
data=cv_image.tobytes() # BGR data
325
)
326
# Note: This may result in color channel swapping
327
```
328
329
## Error Handling
330
331
```python
332
import pillow_heif
333
334
try:
335
# Attempt encoding with invalid parameters
336
pillow_heif.encode(
337
mode="INVALID_MODE",
338
size=(100, 100),
339
data=b"invalid data",
340
fp="output.heic"
341
)
342
except ValueError as e:
343
print(f"Invalid parameters: {e}")
344
except IOError as e:
345
print(f"Encoding failed: {e}")
346
except Exception as e:
347
print(f"Unexpected error: {e}")
348
349
# Safe encoding with validation
350
def safe_encode(mode, size, data, fp, **kwargs):
351
"""Safely encode with parameter validation."""
352
valid_modes = ['RGB', 'RGBA', 'L', 'LA']
353
if mode not in valid_modes:
354
raise ValueError(f"Mode must be one of {valid_modes}")
355
356
expected_size = size[0] * size[1] * len(mode)
357
if len(data) != expected_size:
358
raise ValueError(f"Data size mismatch: expected {expected_size}, got {len(data)}")
359
360
return pillow_heif.encode(mode, size, data, fp, **kwargs)
361
```