0
# Utilities and Constants
1
2
Utility functions for extracting XMP data to Python dictionaries, comprehensive XMP constants for namespaces and options, and library management functions.
3
4
## Capabilities
5
6
### Utility Functions
7
8
#### Data Extraction
9
10
```python { .api }
11
def object_to_dict(xmp):
12
"""
13
Extract all XMP data from XMPMeta object into standard Python dictionary.
14
15
Parameters:
16
- xmp: XMPMeta instance
17
18
Returns:
19
dict: Standard Python dictionary with XMP data organized by namespace
20
"""
21
22
def file_to_dict(file_path):
23
"""
24
Extract XMP data from file into dictionary.
25
26
Parameters:
27
- file_path: str, path to file
28
29
Returns:
30
dict: Dictionary with XMP data (empty if no valid XMP found)
31
32
Raises:
33
IOError: if file doesn't exist
34
"""
35
```
36
37
#### Library Management
38
39
```python { .api }
40
def terminate():
41
"""
42
Terminate library usage for memory cleanup.
43
44
Warning: Calling this crashes Python if libxmp methods are used afterward.
45
Only call when completely done with XMP operations.
46
"""
47
```
48
49
### XMP Constants
50
51
#### Standard Namespaces
52
53
```python { .api }
54
# Core XMP namespaces
55
XMP_NS_XMP = "http://ns.adobe.com/xap/1.0/"
56
XMP_NS_XMP_Rights = "http://ns.adobe.com/xap/1.0/rights/"
57
XMP_NS_XMP_MM = "http://ns.adobe.com/xap/1.0/mm/"
58
XMP_NS_XMP_BJ = "http://ns.adobe.com/xap/1.0/bj/"
59
60
# Dublin Core
61
XMP_NS_DC = "http://purl.org/dc/elements/1.1/"
62
63
# IPTC Core
64
XMP_NS_IPTCCore = "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
65
66
# Adobe application namespaces
67
XMP_NS_Photoshop = "http://ns.adobe.com/photoshop/1.0/"
68
XMP_NS_CameraRaw = "http://ns.adobe.com/camera-raw-settings/1.0/"
69
XMP_NS_CameraRawSavedSettings = "http://ns.adobe.com/camera-raw-saved-settings/1.0/"
70
71
# Document formats
72
XMP_NS_PDF = "http://ns.adobe.com/pdf/1.3/"
73
XMP_NS_PDFX = "http://ns.adobe.com/pdfx/1.3/"
74
75
# Technical namespaces
76
XMP_NS_TIFF = "http://ns.adobe.com/tiff/1.0/"
77
XMP_NS_EXIF = "http://ns.adobe.com/exif/1.0/"
78
XMP_NS_EXIF_Aux = "http://ns.adobe.com/exif/1.0/aux/"
79
80
# Image formats
81
XMP_NS_PNG = "http://ns.adobe.com/png/1.0/"
82
XMP_NS_JPEG = "http://ns.adobe.com/jpeg/1.0/"
83
XMP_NS_JP2K = "http://ns.adobe.com/jp2k/1.0/"
84
XMP_NS_SWF = "http://ns.adobe.com/swf/1.0/"
85
86
# Media formats
87
XMP_NS_DM = "http://ns.adobe.com/xmp/1.0/DynamicMedia/"
88
XMP_NS_ASF = "http://ns.adobe.com/asf/1.0/"
89
XMP_NS_WAV = "http://ns.adobe.com/xmp/wav/1.0/"
90
91
# Adobe applications
92
XMP_NS_PSAlbum = "http://ns.adobe.com/album/1.0/"
93
XMP_NS_Lightroom = "http://ns.adobe.com/lightroom/1.0/"
94
XMP_NS_AdobeStockPhoto = "http://ns.adobe.com/StockPhoto/1.0/"
95
XMP_NS_CreatorAtom = "http://ns.adobe.com/creatorAtom/1.0/"
96
97
# XMP structure types
98
XMP_NS_XMP_Note = "http://ns.adobe.com/xmp/note/"
99
XMP_NS_XMP_IdentifierQual = "http://ns.adobe.com/xmp/Identifier/qual/1.0/"
100
XMP_NS_XMP_Dimensions = "http://ns.adobe.com/xap/1.0/sType/Dimensions#"
101
XMP_NS_XMP_Text = "http://ns.adobe.com/xap/1.0/t/"
102
XMP_NS_XMP_PagedFile = "http://ns.adobe.com/xap/1.0/t/pg/"
103
XMP_NS_XMP_Graphics = "http://ns.adobe.com/xap/1.0/g/"
104
XMP_NS_XMP_Image = "http://ns.adobe.com/xap/1.0/g/img/"
105
XMP_NS_XMP_Font = "http://ns.adobe.com/xap/1.0/sType/Font#"
106
XMP_NS_XMP_ResourceEvent = "http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
107
XMP_NS_XMP_ResourceRef = "http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
108
XMP_NS_XMP_ST_Version = "http://ns.adobe.com/xap/1.0/sType/Version#"
109
XMP_NS_XMP_ST_Job = "http://ns.adobe.com/xap/1.0/sType/Job#"
110
XMP_NS_XMP_ManifestItem = "http://ns.adobe.com/xap/1.0/sType/ManifestItem#"
111
112
# Standards and schemas
113
XMP_NS_DICOM = "http://ns.adobe.com/DICOM/"
114
XMP_NS_PDFA_Schema = "http://www.aiim.org/pdfa/ns/schema#"
115
XMP_NS_PDFA_Property = "http://www.aiim.org/pdfa/ns/property#"
116
XMP_NS_PDFA_Type = "http://www.aiim.org/pdfa/ns/type#"
117
XMP_NS_PDFA_Field = "http://www.aiim.org/pdfa/ns/field#"
118
XMP_NS_PDFA_ID = "http://www.aiim.org/pdfa/ns/id/"
119
XMP_NS_PDFA_Extension = "http://www.aiim.org/pdfa/ns/extension/"
120
XMP_NS_PDFX_ID = "http://www.npes.org/pdfx/ns/id/"
121
XMP_NS_CC = "http://creativecommons.org/ns#"
122
XMP_NS_AVM = "http://www.communicatingastronomy.org/avm/1.0/"
123
124
# XML and RDF
125
XMP_NS_XML = "http://www.w3.org/XML/1998/namespace"
126
XMP_NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
127
XMP_NS_XMPMeta = "adobe:ns:meta/"
128
```
129
130
#### File Format Constants
131
132
```python { .api }
133
# Document formats
134
XMP_FT_PDF = 0x50444620 # 'PDF '
135
XMP_FT_PS = 0x50532020 # 'PS ' PostScript
136
XMP_FT_EPS = 0x45505320 # 'EPS ' Encapsulated PostScript
137
138
# Image formats
139
XMP_FT_JPEG = 0x4A504547 # 'JPEG'
140
XMP_FT_JPEG2K = 0x4A505820 # 'JPX ' ISO 15444-1
141
XMP_FT_TIFF = 0x54494646 # 'TIFF'
142
XMP_FT_GIF = 0x47494620 # 'GIF '
143
XMP_FT_PNG = 0x504E4720 # 'PNG '
144
145
# Media formats
146
XMP_FT_SWF = 0x53574620 # 'SWF '
147
XMP_FT_FLA = 0x464C4120 # 'FLA '
148
XMP_FT_FLV = 0x464C5620 # 'FLV '
149
XMP_FT_MOV = 0x4D4F5620 # 'MOV ' Quicktime
150
XMP_FT_AVI = 0x41564920 # 'AVI '
151
XMP_FT_MPEG = 0x4D504547 # 'MPEG'
152
XMP_FT_MPEG2 = 0x4D503220 # 'MP2 '
153
XMP_FT_MPEG4 = 0x4D503420 # 'MP4 ' ISO 14494-12 and -14
154
155
# Audio formats
156
XMP_FT_WAV = 0x57415620 # 'WAV '
157
XMP_FT_MP3 = 0x4D503320 # 'MP3 '
158
XMP_FT_AIFF = 0x41494646 # 'AIFF'
159
XMP_FT_WMAV = 0x574D4156 # 'WMAV' Windows Media Audio and Video
160
161
# Adobe applications
162
XMP_FT_PHOTOSHOP = 0x50534420 # 'PSD '
163
XMP_FT_ILLUSTRATOR = 0x41492020 # 'AI '
164
XMP_FT_INDESIGN = 0x494E4444 # 'INDD'
165
XMP_FT_AEPROJECT = 0x41455020 # 'AEP ' After Effects Project
166
XMP_FT_AEPROJTEMPLATE = 0x41455420 # 'AET ' After Effects Project Template
167
XMP_FT_AEFILTERPRESET = 0x46465820 # 'FFX ' After Effects Filter Preset
168
XMP_FT_ENCOREPROJECT = 0x4E434F52 # 'NCOR'
169
XMP_FT_PREMIEREPROJECT = 0x5052504A # 'PRPJ'
170
XMP_FT_PREMIERETITLE = 0x5052544C # 'PRTL'
171
172
# Other formats
173
XMP_FT_CIN = 0x43494E20 # 'CIN ' Cineon
174
XMP_FT_SES = 0x53455320 # 'SES ' Audition session
175
XMP_FT_CEL = 0x43454C20 # 'CEL ' Audition loop
176
XMP_FT_HTML = 0x48544D4C # 'HTML'
177
XMP_FT_XML = 0x584D4C20 # 'XML '
178
XMP_FT_TEXT = 0x74657874 # 'text'
179
XMP_FT_UNKNOWN = 0x20202020 # Default/unknown
180
```
181
182
#### Property Options
183
184
```python { .api }
185
# Property type flags
186
XMP_PROP_VALUE_IS_URI = 0x00000002
187
XMP_PROP_HAS_QUALIFIERS = 0x00000010
188
XMP_PROP_IS_QUALIFIER = 0x00000020
189
XMP_PROP_HAS_LANG = 0x00000040
190
XMP_PROP_HAS_TYPE = 0x00000080
191
XMP_PROP_VALUE_IS_STRUCT = 0x00000100
192
XMP_PROP_VALUE_IS_ARRAY = 0x00000200
193
XMP_PROP_ARRAY_IS_UNORDERED = 0x00000000
194
XMP_PROP_ARRAY_IS_ORDERED = 0x00000400
195
XMP_PROP_ARRAY_IS_ALT = 0x00000800
196
XMP_PROP_ARRAY_IS_ALTTEXT = 0x00001000
197
```
198
199
#### Serialization Options
200
201
```python { .api }
202
XMP_SERIAL_OMITPACKETWRAPPER = 0x0010 # Omit XMP packet wrapper
203
XMP_SERIAL_READONLYPACKET = 0x0020 # Mark packet as read-only
204
XMP_SERIAL_USECOMPACTFORMAT = 0x0040 # Use compact RDF formatting
205
XMP_SERIAL_INCLUDETHUMBNAILPAD = 0x0100 # Include padding for thumbnail
206
XMP_SERIAL_EXACTPACKETLENGTH = 0x0200 # Exact packet length
207
XMP_SERIAL_WRITEALIASCOMMENTS = 0x0400 # Write alias comments
208
XMP_SERIAL_OMITALLFORMATTING = 0x0800 # Omit all formatting
209
```
210
211
#### Iterator Options
212
213
```python { .api }
214
XMP_ITER_PROPERTIES = 0x0000 # Iterate all properties
215
XMP_ITER_JUSTCHILDREN = 0x0100 # Just immediate children
216
XMP_ITER_JUSTLEAFNODES = 0x0200 # Just leaf nodes
217
XMP_ITER_JUSTLEAFNAME = 0x0400 # Just leaf names
218
XMP_ITER_INCLUDEALIASES = 0x0800 # Include alias properties
219
XMP_ITER_OMITQUALIFIERS = 0x1000 # Omit qualifier properties
220
```
221
222
#### File Operation Options
223
224
```python { .api }
225
# File open options
226
XMP_OPEN_NOOPTION = 0x00000000 # No open option
227
XMP_OPEN_READ = 0x00000001 # Open for read-only access
228
XMP_OPEN_FORUPDATE = 0x00000002 # Open for reading and writing
229
XMP_OPEN_ONLYXMP = 0x00000004 # Only XMP wanted, allows optimizations
230
XMP_OPEN_CACHETNAIL = 0x00000008 # Cache thumbnail if possible
231
XMP_OPEN_STRICTLY = 0x00000010 # Be strict about locating XMP
232
XMP_OPEN_USESMARTHANDLER = 0x00000020 # Require smart handler use
233
XMP_OPEN_USEPACKETSCANNING = 0x00000040 # Force packet scanning
234
XMP_OPEN_LIMITSCANNING = 0x00000080 # Only scan files known to need it
235
XMP_OPEN_INBACKGROUND = 0x10000000 # Set if calling from background thread
236
237
# File close options
238
XMP_CLOSE_NOOPTION = 0x0000 # No close option
239
XMP_CLOSE_SAFEUPDATE = 0x0001 # Write to temp file and swap for safety
240
```
241
242
#### Option Utility Functions
243
244
```python { .api }
245
def has_option(xmp_option, bitmask):
246
"""
247
Check if option bit is set in bitmask.
248
249
Parameters:
250
- xmp_option: int, option value to check
251
- bitmask: int, bitmask to check against
252
253
Returns:
254
bool: True if option bit is set
255
"""
256
257
def options_mask(xmp_options, **kwargs):
258
"""
259
Convert option dictionary and keyword arguments to bitmask.
260
261
Parameters:
262
- xmp_options: dict, option name to constant mappings
263
- **kwargs: keyword arguments with option names
264
265
Returns:
266
int: Combined bitmask for all specified options
267
"""
268
```
269
270
#### Option Dictionaries
271
272
```python { .api }
273
# Serialization options mapping
274
XMP_SERIAL_OPTIONS = {
275
'omit_packet_wrapper': XMP_SERIAL_OMITPACKETWRAPPER,
276
'read_only_packet': XMP_SERIAL_READONLYPACKET,
277
'use_compact_format': XMP_SERIAL_USECOMPACTFORMAT,
278
'include_thumbnail_pad': XMP_SERIAL_INCLUDETHUMBNAILPAD,
279
'exact_packet_length': XMP_SERIAL_EXACTPACKETLENGTH,
280
'write_alias_comments': XMP_SERIAL_WRITEALIASCOMMENTS,
281
'omit_all_formatting': XMP_SERIAL_OMITALLFORMATTING
282
}
283
284
# Property options mapping
285
XMP_PROP_OPTIONS = {
286
'value_is_uri': XMP_PROP_VALUE_IS_URI,
287
'has_qualifiers': XMP_PROP_HAS_QUALIFIERS,
288
'is_qualifier': XMP_PROP_IS_QUALIFIER,
289
'has_lang': XMP_PROP_HAS_LANG,
290
'has_type': XMP_PROP_HAS_TYPE,
291
'value_is_struct': XMP_PROP_VALUE_IS_STRUCT,
292
'value_is_array': XMP_PROP_VALUE_IS_ARRAY,
293
'array_is_ordered': XMP_PROP_ARRAY_IS_ORDERED,
294
'array_is_alt': XMP_PROP_ARRAY_IS_ALT,
295
'array_is_alttext': XMP_PROP_ARRAY_IS_ALTTEXT
296
}
297
298
# Open file options mapping
299
XMP_OPEN_OPTIONS = {
300
'open_nooption': XMP_OPEN_NOOPTION,
301
'open_read': XMP_OPEN_READ,
302
'open_forupdate': XMP_OPEN_FORUPDATE,
303
'open_onlyxmp': XMP_OPEN_ONLYXMP,
304
'open_cachetnail': XMP_OPEN_CACHETNAIL,
305
'open_strictly': XMP_OPEN_STRICTLY,
306
'open_usesmarthandler': XMP_OPEN_USESMARTHANDLER,
307
'open_usepacketscanning': XMP_OPEN_USEPACKETSCANNING,
308
'open_limitscanning': XMP_OPEN_LIMITSCANNING,
309
'open_inbackground': XMP_OPEN_INBACKGROUND
310
}
311
312
# Close file options mapping
313
XMP_CLOSE_OPTIONS = {
314
'close_nooption': XMP_CLOSE_NOOPTION,
315
'close_safeupdate': XMP_CLOSE_SAFEUPDATE
316
}
317
```
318
319
## Usage Examples
320
321
### Data Extraction to Dictionary
322
323
```python
324
from libxmp import XMPMeta
325
from libxmp.utils import object_to_dict, file_to_dict
326
327
# Extract from XMPMeta object
328
xmp = XMPMeta()
329
xmp.set_property("http://ns.adobe.com/xap/1.0/", "CreatorTool", "Python")
330
xmp.set_property("http://purl.org/dc/elements/1.1/", "creator", "John Doe")
331
332
# Convert to dictionary
333
xmp_dict = object_to_dict(xmp)
334
print(xmp_dict)
335
# Output: {
336
# 'http://ns.adobe.com/xap/1.0/': {'CreatorTool': 'Python'},
337
# 'http://purl.org/dc/elements/1.1/': {'creator': 'John Doe'}
338
# }
339
340
# Extract directly from file
341
file_dict = file_to_dict("photo.jpg")
342
if file_dict:
343
print("File contains XMP metadata:")
344
for namespace, properties in file_dict.items():
345
print(f" {namespace}:")
346
for prop, value in properties.items():
347
print(f" {prop}: {value}")
348
else:
349
print("No XMP metadata found in file")
350
```
351
352
### Working with Constants and Options
353
354
```python
355
from libxmp import XMPMeta
356
from libxmp.consts import *
357
358
# Using namespace constants
359
xmp = XMPMeta()
360
xmp.set_property(XMP_NS_DC, "creator", "John Doe")
361
xmp.set_property(XMP_NS_XMP, "CreatorTool", "Python XMP Toolkit")
362
xmp.set_property(XMP_NS_Photoshop, "ColorMode", "RGB")
363
364
# Using serialization options with keyword arguments
365
xmp_str = xmp.serialize_to_str(
366
use_compact_format=True,
367
omit_packet_wrapper=True
368
)
369
370
# Using property options
371
xmp.set_property(
372
XMP_NS_DC,
373
"rights",
374
"Copyright 2024",
375
value_is_uri=False
376
)
377
378
# Create ordered array
379
xmp.append_array_item(
380
XMP_NS_DC,
381
"creator",
382
"First Author",
383
array_is_ordered=True
384
)
385
```
386
387
### Option Utility Functions
388
389
```python
390
from libxmp.consts import has_option, options_mask, XMP_PROP_OPTIONS
391
392
# Check if specific option is set
393
prop_options = 0x00000210 # Some combined options
394
if has_option(prop_options, XMP_PROP_HAS_QUALIFIERS):
395
print("Property has qualifiers")
396
397
if has_option(prop_options, XMP_PROP_VALUE_IS_STRUCT):
398
print("Property is a structure")
399
400
# Create option mask from keywords
401
mask = options_mask(XMP_PROP_OPTIONS,
402
value_is_struct=True,
403
has_qualifiers=True)
404
print(f"Combined option mask: {mask}")
405
```
406
407
### Standard Namespace Usage
408
409
```python
410
from libxmp import XMPMeta
411
from libxmp.consts import *
412
413
def set_image_metadata(file_path, metadata):
414
"""Set comprehensive image metadata using standard namespaces."""
415
from libxmp import XMPFiles
416
417
xmpfile = XMPFiles(file_path=file_path)
418
xmp = xmpfile.get_xmp() or XMPMeta()
419
420
# Dublin Core metadata
421
if 'title' in metadata:
422
xmp.set_localized_text(XMP_NS_DC, "title", "x-default", "en-US", metadata['title'])
423
if 'creator' in metadata:
424
xmp.set_property(XMP_NS_DC, "creator", metadata['creator'])
425
if 'description' in metadata:
426
xmp.set_localized_text(XMP_NS_DC, "description", "x-default", "en-US", metadata['description'])
427
if 'keywords' in metadata:
428
for keyword in metadata['keywords']:
429
xmp.append_array_item(XMP_NS_DC, "subject", keyword)
430
431
# XMP Basic metadata
432
if 'creator_tool' in metadata:
433
xmp.set_property(XMP_NS_XMP, "CreatorTool", metadata['creator_tool'])
434
if 'create_date' in metadata:
435
xmp.set_property_datetime(XMP_NS_XMP, "CreateDate", metadata['create_date'])
436
437
# Rights management
438
if 'rights' in metadata:
439
xmp.set_localized_text(XMP_NS_XMP_Rights, "UsageTerms", "x-default", "en-US", metadata['rights'])
440
441
# Photoshop-specific metadata
442
if 'color_mode' in metadata:
443
xmp.set_property(XMP_NS_Photoshop, "ColorMode", str(metadata['color_mode']))
444
445
# IPTC Core metadata
446
if 'location' in metadata:
447
xmp.set_property(XMP_NS_IPTCCore, "Location", metadata['location'])
448
449
xmpfile.put_xmp(xmp)
450
xmpfile.close_file()
451
452
# Usage
453
metadata = {
454
'title': 'Sunset Over Mountains',
455
'creator': 'Jane Photographer',
456
'description': 'Beautiful sunset photograph taken in the mountains',
457
'keywords': ['sunset', 'mountains', 'landscape', 'nature'],
458
'creator_tool': 'Python XMP Toolkit',
459
'rights': 'Copyright 2024 Jane Photographer. All rights reserved.',
460
'color_mode': 3, # RGB
461
'location': 'Rocky Mountains, Colorado'
462
}
463
464
set_image_metadata("sunset.jpg", metadata)
465
```
466
467
### Memory Management
468
469
```python
470
from libxmp.utils import terminate
471
from libxmp import XMPMeta, XMPFiles
472
473
# Process many files
474
files = ["img1.jpg", "img2.jpg", "img3.jpg"] # ... many files
475
476
for file_path in files:
477
try:
478
xmpfile = XMPFiles(file_path=file_path)
479
xmp = xmpfile.get_xmp()
480
# ... process XMP data
481
xmpfile.close_file()
482
except Exception as e:
483
print(f"Error processing {file_path}: {e}")
484
485
# When completely done with all XMP operations
486
# (only call this at program end)
487
try:
488
terminate()
489
print("XMP library terminated successfully")
490
except:
491
pass # Ignore termination errors
492
```