Pillow
Pillow copied to clipboard
Add XMP writing
This is a feature request: As a followup of this discussion it might be possible to add a simple XMP write support using the provided infrastructure (that is by passing image.encoderinfo["extra"]). This approach doesn't account for large XMP Data (>64Kb), but would be an improvement.
For an discussion on XMP, especially large XMP fields, see #5076, there are also sample images linked.
To keep the interface simple, it should only accept str in the first iteration, later on some XML structure, requirements for a dict interface would need full support for the XML data model like XML namespace support and lists of elements with the same name.
See also #8069
a little thoughts:
-
the parameter to the
Image.savefunction is best to callxmp(for encoder probably too?) -
the parameter type is preferred to be bytes at first stage (different image formats may require different encoding, it will not always be UTF-8) - in future it can be
strordict, butbytesshould be supported, imho.
From my reading of https://github.com/python-pillow/Pillow/discussions/8269#discussioncomment-10201110, you're requesting this for both JPEG and MPO?
It's certainly easier to focus on JPEG first, but I wouldn't mind if MPO is also covered. Especially since this would enable creating UltraHDR JPEGs as well. but I suspect this to be a minor use case currently.
Great, thanks! exiftool reports entries from faked entry using the linked PR. Is there another test you would to be conducted? I don't have Photoshop or similar...
The PR will actually allow XMP data to be written to both JPEG and MPO images.
from PIL import Image
for ext in ('.jpg', '.mpo'):
with Image.open("Tests/images/hopper.png") as im:
im.save('out'+ext, xmp=b"XMP test")
with Image.open('out'+ext) as reloaded:
assert reloaded.info["xmp"] == b"XMP test"
@radarhere: Yes thanks! I could already confirm it. But I wasn't able to add a valid XMP entry to the second image of an MPO. But haven't checked / investigated for a few weeks.
I've pushed a commit to the PR so that it uses the image's info dictionary as well. That will allow you to do this -
from PIL import Image
im = Image.open("Tests/images/hopper.png")
second_im = Image.new("RGB", (128, 128))
second_im.info["xmp"] = b"Second frame"
im.save("out.mpo", save_all=True, append_images=[second_im])
While the change for this was released in Pillow 11, my plan to allow im.info["xmp"] to be used for MPO frames has met some resistance - #8479
I've created #8483 with a new plan, using im.encoderinfo to set XMP data for MPO frames.