AI Metadata Preservation Test: XMP Before and After PNG Resizing

AI Metadata Preservation Test: XMP Before and After PNG Resizing

Rewarx practical lab · November 3, 2026 · Synthetic fixtures

AI Metadata Preservation Test: XMP Before and After PNG Resizing

We created one synthetic PNG with a deliberately seeded IPTC-XMP DigitalSourceType field and EXIF Artist value, then ran three local transformations using Python 3.9.6 and Pillow 11.3.0. Default save and resize lost both tested fields. Explicitly supplying the XMP and EXIF during resize preserved them. This is a reproducible local fixture test, not a marketplace study or a Shopify CDN test.

Actual results

OutputDimensionsIPTC-XMP fieldEXIF ArtistC2PA
synthetic-source.png600 × 600PresentSynthetic metadata fixtureNot tested
reencoded-default.png600 × 600AbsentAbsentNot tested
resized-default.png500 × 500AbsentAbsentNot tested
resized-preserved.png500 × 500PresentSynthetic metadata fixtureNot tested

The sample pixels are programmatically generated. The trainedAlgorithmicMedia value is intentionally seeded test data; it is not a claim that this synthetic fixture was created by a trained model. Never infer genuine provenance from the mere presence of this writable field.

Three different concepts

ConceptWhat this experiment checks
EXIFA separate metadata structure; Artist was used only as a control value.
IPTC-XMPA DigitalSourceType property inside an XMP packet; XML parsing checked the actual property.
C2PASigned provenance assertions and validation. No C2PA manifest, signature or trust chain was created or tested.

An EXIF field does not stand in for IPTC-XMP. Copying an XMP packet does not create or validate C2PA credentials. A modification can require a provenance-aware workflow; do not claim a signature remained valid just because metadata bytes survived.

Why preserve source disclosures

Google Merchant Center requires AI-generated images to retain the relevant IPTC DigitalSourceType metadata. It explicitly says not to remove embedded AI source tags. Read the official AI-generated content policy. This experiment demonstrates a loss mode and a local preservation control; it is not a recipe for removing disclosure from product assets.

Use accurate source classifications for real assets. The fixture below is isolated test material. Do not copy a synthetic label into unrelated real photography or overwrite an asset’s authentic source information.

Reproduce the local experiment

Save this as metadata_preservation_lab.py, install Pillow, and choose a new output directory. The script refuses to overwrite an existing synthetic source. It creates a source, default re-encode, default resize and explicit preservation variant, then parses the outputs and writes results.json.

python -m pip install Pillow==11.3.0
python metadata_preservation_lab.py fresh-metadata-test
Complete experiment source
"""Synthetic local PNG XMP/EXIF experiment. Not a C2PA or Shopify CDN test.
python metadata_preservation_lab.py OUTPUT_DIRECTORY
Requires Pillow. Never run over a real product source directory.
"""
import json,sys,platform,xml.etree.ElementTree as ET
from pathlib import Path
import PIL
from PIL import Image,PngImagePlugin

TAG='http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia'
XMP=('<?xpacket begin=""?><x:xmpmeta xmlns:x="adobe:ns:meta/">'
     '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">'
     '<rdf:Description xmlns:d="http://iptc.org/std/Iptc4xmpExt/2008-02-29/" '
     'd:DigitalSourceType="'+TAG+'"/></rdf:RDF></x:xmpmeta><?xpacket end="w"?>')

def read_tags(path):
    with Image.open(path) as im:
        packet=im.info.get('XML:com.adobe.xmp','')
        root=ET.fromstring(packet) if packet else None
        values=[]
        if root is not None:
            for node in root.iter():
                values.extend(v for k,v in node.attrib.items() if k.endswith('}DigitalSourceType'))
        return {'file':Path(path).name,'dimensions':list(im.size),'xmp_present':bool(packet),
                'digital_source_type':values,'exif_artist':im.getexif().get(315),'c2pa_tested':False}

def run(out):
    out=Path(out);out.mkdir(parents=True,exist_ok=True)
    src=out/'synthetic-source.png'
    if src.exists():raise ValueError('Use a fresh output directory to protect previous runs')
    # This is a metadata fixture, not a claim that these programmatic pixels were generated by a trained AI.
    info=PngImagePlugin.PngInfo();info.add_itxt('XML:com.adobe.xmp',XMP)
    exif=Image.Exif();exif[315]='Synthetic metadata fixture'
    Image.new('RGB',(600,600),(38,95,82)).save(src,pnginfo=info,exif=exif)
    with Image.open(src) as im:
        im.save(out/'reencoded-default.png')
        im.resize((500,500)).save(out/'resized-default.png')
        keep=PngImagePlugin.PngInfo();keep.add_itxt('XML:com.adobe.xmp',im.info['XML:com.adobe.xmp'])
        im.resize((500,500)).save(out/'resized-preserved.png',pnginfo=keep,exif=im.getexif())
    rows=[read_tags(out/n) for n in ['synthetic-source.png','reencoded-default.png','resized-default.png','resized-preserved.png']]
    result={'scope':'Synthetic PNG fixture with deliberately seeded XMP; no real product or Shopify CDN tested','python':platform.python_version(),'pillow':PIL.__version__,'rows':rows}
    (out/'results.json').write_text(json.dumps(result,indent=2));return result

if __name__=='__main__':print(json.dumps(run(sys.argv[1]),indent=2))
Actual machine-readable results
{
  "scope": "Synthetic PNG fixture with deliberately seeded XMP; no real product or Shopify CDN tested",
  "python": "3.9.6",
  "pillow": "11.3.0",
  "rows": [
    {
      "file": "synthetic-source.png",
      "dimensions": [
        600,
        600
      ],
      "xmp_present": true,
      "digital_source_type": [
        "http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia"
      ],
      "exif_artist": "Synthetic metadata fixture",
      "c2pa_tested": false
    },
    {
      "file": "reencoded-default.png",
      "dimensions": [
        600,
        600
      ],
      "xmp_present": false,
      "digital_source_type": [],
      "exif_artist": null,
      "c2pa_tested": false
    },
    {
      "file": "resized-default.png",
      "dimensions": [
        500,
        500
      ],
      "xmp_present": false,
      "digital_source_type": [],
      "exif_artist": null,
      "c2pa_tested": false
    },
    {
      "file": "resized-preserved.png",
      "dimensions": [
        500,
        500
      ],
      "xmp_present": true,
      "digital_source_type": [
        "http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia"
      ],
      "exif_artist": "Synthetic metadata fixture",
      "c2pa_tested": false
    }
  ]
}

What the experiment does not establish

  • It does not measure metadata survival across a real merchant catalog.
  • It does not test JPEG, WebP, AVIF or every Pillow version. Current documentation can describe newer behavior; rerun for your deployed version.
  • It does not upload to Shopify, test Shopify image transformations or establish any marketplace stripping policy.
  • It does not measure C2PA signature validity or anti-tampering properties.
  • It does not prove that preserving these two fields makes an asset compliant with all platform requirements.

Apply the method to your own pipeline

Keep an original in a separate archive. Make a staging copy and record the exact tool versions and transformation command. Inspect the required field on the output, then repeat after each authorized export or delivery stage. For signed provenance, use appropriate C2PA validation rather than this XML-property check. If a stage loses a required disclosure, repair the workflow before publishing and verify again.

Related practical guides

  • Feed image dimension preflight
  • Variant image CSV preflight
  • IPTC source type reference
  • Product image accuracy and disclaimers

Sources checked November 3, 2026

  • Google AI-generated image policy
  • IPTC Digital Source Type vocabulary
  • Pillow image format documentation
  • C2PA 2.2 specification, a versioned technical reference

Rewarx workflow entry

Inspect the Rewarx background-removal entry page. Its primary button leads to Studio authentication. The validators and metadata lab here run locally; this article does not claim the Studio performs these checks or preserves metadata automatically.

https://www.rewarx.com/blogs/ai-metadata-preservation-test

Rewarx Studio | AI-Powered Product Photography & Image Generator

Turn snapshots into professional, high-converting product photos in batches. Cut costs by 90% and launch your collection in minutes.

Create Stunning Product Photos in Batches

Rewarx Studio is fine-tuned to understand the material physics and lighting requirements of 20+ specialized industries, including electronics, cosmetics, fashion, jewelry, home decor, and beverages.

Our virtual photography studio provides precise control over lighting, depth, and material textures. Perfect for high-end catalog shots, Etsy, Amazon, Shopify, and eBay sellers.

The Full AI Production Suite

  • AI Photography Studio: Professional virtual photography with precise control over lighting and textures.
  • AI Lookalike Creator: Match the aesthetic, lighting, and composition of any reference photo.
  • AI Model Studio: Integrate professional human models with your products naturally with realistic shadows.
  • AI Ghost Mannequin: Create a 3D "Invisible" mannequin effect showing inner linings and volume.
  • AI Mockup Generator: Apply patterns and graphics onto 3D items with absolute physical accuracy.
  • AI Group Shot Studio: Cohesively synthesize multiple products into a single scene with perfect lighting.
  • AI Product Page Builder: Generate conversion-optimized listing asset sets in a single click.
  • AI Commercial Ad Poster: Combine product focal points with premium typography for high-converting ads.

Corporate Headquarters

Rewarx Limited, Suite 400, 548 Market Street, San Francisco, CA 94104, United States. Email: studio@rewarx.com