0
# Images and Shapes
1
2
Image insertion and inline shape management with sizing, positioning, and format controls. Provides comprehensive support for adding and manipulating visual elements in documents.
3
4
## Capabilities
5
6
### Image Insertion
7
8
Add images to documents with flexible sizing and format options.
9
10
```python { .api }
11
class Document:
12
def add_picture(self, image_path_or_stream, width=None, height=None):
13
"""Add an image to the document.
14
15
Args:
16
image_path_or_stream (str or file-like): Path to image file or file-like object
17
width (Length, optional): Image width (maintains aspect ratio if height not specified)
18
height (Length, optional): Image height (maintains aspect ratio if width not specified)
19
20
Returns:
21
InlineShape: New inline shape containing the image
22
"""
23
24
class Run:
25
def add_picture(self, image_path_or_stream, width=None, height=None):
26
"""Add an inline picture to the run.
27
28
Args:
29
image_path_or_stream (str or file-like): Path to image file or file-like object
30
width (Length, optional): Picture width
31
height (Length, optional): Picture height
32
33
Returns:
34
InlineShape: New inline shape object
35
"""
36
```
37
38
**Usage Examples:**
39
40
```python
41
from docx.shared import Inches, Cm
42
43
# Add image to document with automatic sizing
44
doc.add_picture('photo.jpg')
45
46
# Add image with specific width (height auto-calculated)
47
doc.add_picture('photo.jpg', width=Inches(2))
48
49
# Add image with specific dimensions
50
doc.add_picture('photo.jpg', width=Inches(3), height=Inches(2))
51
52
# Add image from file-like object
53
with open('image.png', 'rb') as image_file:
54
doc.add_picture(image_file, width=Cm(5))
55
56
# Add image to specific run
57
para = doc.add_paragraph('Text with image: ')
58
run = para.add_run()
59
run.add_picture('icon.png', width=Inches(0.5))
60
para.add_run(' more text after image.')
61
```
62
63
### Inline Shape Management
64
65
Access and manage inline shapes collection in documents.
66
67
```python { .api }
68
class Document:
69
@property
70
def inline_shapes(self):
71
"""Collection of all inline shapes in document.
72
73
Returns:
74
InlineShapes: Collection of inline shape objects
75
"""
76
77
class InlineShapes:
78
def add_picture(self, image_path_or_stream, width=None, height=None):
79
"""Add a picture as an inline shape.
80
81
Args:
82
image_path_or_stream (str or file-like): Image file path or stream
83
width (Length, optional): Picture width
84
height (Length, optional): Picture height
85
86
Returns:
87
InlineShape: New picture inline shape
88
"""
89
90
def __len__(self):
91
"""Number of inline shapes in collection."""
92
93
def __iter__(self):
94
"""Iterate over inline shapes."""
95
96
def __getitem__(self, index):
97
"""Access inline shape by index."""
98
```
99
100
**Usage Examples:**
101
102
```python
103
# Access inline shapes collection
104
shapes = doc.inline_shapes
105
106
# Add picture through shapes collection
107
shape = shapes.add_picture('diagram.png', width=Inches(4))
108
109
# Count and iterate through shapes
110
print(f"Document has {len(shapes)} inline shapes")
111
112
for i, shape in enumerate(shapes):
113
print(f"Shape {i}: {shape.type} ({shape.width} x {shape.height})")
114
115
# Access specific shape
116
first_shape = shapes[0]
117
print(f"First shape type: {first_shape.type}")
118
```
119
120
### Inline Shape Properties
121
122
Properties and methods for individual inline shapes.
123
124
```python { .api }
125
class InlineShape:
126
@property
127
def width(self):
128
"""Shape width (read/write).
129
130
Returns:
131
Length: Shape width
132
"""
133
134
@width.setter
135
def width(self, value):
136
"""Set shape width."""
137
138
@property
139
def height(self):
140
"""Shape height (read/write).
141
142
Returns:
143
Length: Shape height
144
"""
145
146
@height.setter
147
def height(self, value):
148
"""Set shape height."""
149
150
@property
151
def type(self):
152
"""Shape type.
153
154
Returns:
155
WD_INLINE_SHAPE_TYPE: Type of inline shape
156
"""
157
```
158
159
**Usage Examples:**
160
161
```python
162
from docx.shared import Inches
163
from docx.enum.shape import WD_INLINE_SHAPE_TYPE
164
165
# Add and modify shape
166
shape = doc.add_picture('image.jpg', width=Inches(2))
167
168
# Check shape type
169
if shape.type == WD_INLINE_SHAPE_TYPE.PICTURE:
170
print("This is a picture shape")
171
172
# Resize shape
173
shape.width = Inches(3)
174
shape.height = Inches(2)
175
176
# Get current dimensions
177
print(f"Shape dimensions: {shape.width.inches}\" x {shape.height.inches}\"")
178
179
# Maintain aspect ratio when resizing
180
original_ratio = shape.width / shape.height
181
shape.width = Inches(4)
182
shape.height = Inches(4 / original_ratio)
183
```
184
185
### Image Format Support
186
187
Python-docx supports various image formats with automatic format detection.
188
189
**Supported Formats:**
190
191
- **JPEG** (.jpg, .jpeg) - Most common format for photographs
192
- **PNG** (.png) - Best for images with transparency or crisp graphics
193
- **BMP** (.bmp) - Windows bitmap format
194
- **GIF** (.gif) - Graphics Interchange Format
195
- **TIFF** (.tif, .tiff) - Tagged Image File Format
196
197
**Usage Examples:**
198
199
```python
200
# Add images of different formats
201
doc.add_picture('photo.jpg', width=Inches(3)) # JPEG
202
doc.add_picture('logo.png', width=Inches(2)) # PNG with transparency
203
doc.add_picture('diagram.bmp', width=Inches(4)) # BMP
204
doc.add_picture('animation.gif', width=Inches(2)) # GIF (first frame)
205
doc.add_picture('scan.tiff', width=Inches(5)) # TIFF
206
207
# Format is automatically detected from file content
208
# No need to specify format explicitly
209
```
210
211
### Advanced Image Operations
212
213
More complex image manipulation and positioning.
214
215
**Usage Examples:**
216
217
```python
218
# Create image with calculated dimensions
219
from docx.shared import Inches
220
221
# Add image and store reference
222
image_shape = doc.add_picture('chart.png')
223
224
# Calculate new size maintaining aspect ratio
225
original_width = image_shape.width
226
original_height = image_shape.height
227
aspect_ratio = original_width / original_height
228
229
# Resize to fit specific width
230
target_width = Inches(5)
231
target_height = target_width / aspect_ratio
232
233
image_shape.width = target_width
234
image_shape.height = target_height
235
236
# Add multiple images in a paragraph
237
para = doc.add_paragraph()
238
para.add_run('Before image ')
239
para.add_run().add_picture('small1.png', width=Inches(0.5))
240
para.add_run(' between images ')
241
para.add_run().add_picture('small2.png', width=Inches(0.5))
242
para.add_run(' after images.')
243
244
# Add images with text wrapping (inline only in python-docx)
245
para = doc.add_paragraph('This paragraph contains an inline image ')
246
run = para.add_run()
247
run.add_picture('inline_image.png', width=Inches(1))
248
para.add_run(' that flows with the text like any other character.')
249
```
250
251
### Image Loading from Different Sources
252
253
Load images from various sources including files, URLs, and byte streams.
254
255
**Usage Examples:**
256
257
```python
258
import io
259
import requests
260
from docx import Document
261
from docx.shared import Inches
262
263
# Load from file path
264
doc.add_picture('/path/to/image.jpg', width=Inches(3))
265
266
# Load from file object
267
with open('image.png', 'rb') as img_file:
268
doc.add_picture(img_file, width=Inches(2))
269
270
# Load from URL (download first)
271
response = requests.get('https://example.com/image.jpg')
272
image_stream = io.BytesIO(response.content)
273
doc.add_picture(image_stream, width=Inches(2.5))
274
275
# Load from bytes
276
with open('image.gif', 'rb') as f:
277
image_bytes = f.read()
278
279
image_stream = io.BytesIO(image_bytes)
280
doc.add_picture(image_stream, width=Inches(1.5))
281
282
# Create image from base64 data
283
import base64
284
285
base64_data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
286
image_data = base64.b64decode(base64_data)
287
image_stream = io.BytesIO(image_data)
288
doc.add_picture(image_stream, width=Inches(0.1))
289
```
290
291
### Shape Positioning and Layout
292
293
Control image positioning within document flow.
294
295
**Usage Examples:**
296
297
```python
298
# Images are always inline in python-docx (flow with text)
299
# For layout control, use paragraph formatting
300
301
# Center an image
302
para = doc.add_paragraph()
303
para.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
304
para.add_run().add_picture('centered_image.png', width=Inches(4))
305
306
# Right-align an image
307
para = doc.add_paragraph()
308
para.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
309
para.add_run().add_picture('right_image.png', width=Inches(3))
310
311
# Image with caption
312
img_para = doc.add_paragraph()
313
img_para.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
314
img_para.add_run().add_picture('chart.png', width=Inches(5))
315
316
caption_para = doc.add_paragraph('Figure 1: Sales Chart')
317
caption_para.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
318
caption_para.runs[0].italic = True
319
320
# Image in table cell for positioning
321
table = doc.add_table(rows=1, cols=2)
322
text_cell = table.cell(0, 0)
323
text_cell.text = "Description text here"
324
325
image_cell = table.cell(0, 1)
326
image_para = image_cell.paragraphs[0]
327
image_para.add_run().add_picture('product.jpg', width=Inches(2))
328
```
329
330
### Error Handling
331
332
Handle common image-related errors and exceptions.
333
334
**Usage Examples:**
335
336
```python
337
from docx.image.exceptions import UnrecognizedImageError
338
import os
339
340
def add_image_safely(doc, image_path, width=None):
341
"""Add image with error handling."""
342
try:
343
# Check if file exists
344
if not os.path.exists(image_path):
345
print(f"Image file not found: {image_path}")
346
return None
347
348
# Add image
349
shape = doc.add_picture(image_path, width=width)
350
print(f"Successfully added image: {image_path}")
351
return shape
352
353
except UnrecognizedImageError:
354
print(f"Unsupported image format: {image_path}")
355
return None
356
except Exception as e:
357
print(f"Error adding image {image_path}: {e}")
358
return None
359
360
# Usage
361
shape = add_image_safely(doc, 'photo.jpg', width=Inches(3))
362
if shape:
363
print(f"Image added with dimensions: {shape.width} x {shape.height}")
364
```
365
366
## Types
367
368
```python { .api }
369
from docx.enum.shape import WD_INLINE_SHAPE_TYPE
370
371
class WD_INLINE_SHAPE_TYPE:
372
"""Inline shape type options."""
373
CHART = 3
374
LINKED_PICTURE = 5
375
PICTURE = 1
376
SMART_ART = 15
377
378
# Image-related exceptions
379
from docx.image.exceptions import InvalidImageStreamError, UnexpectedEndOfFileError, UnrecognizedImageError
380
381
class InvalidImageStreamError(Exception):
382
"""Raised when image stream is invalid or corrupted."""
383
384
class UnexpectedEndOfFileError(Exception):
385
"""Raised when image file ends unexpectedly."""
386
387
class UnrecognizedImageError(Exception):
388
"""Raised when image format is not recognized or supported."""
389
```