$values) {
foreach ((array) $values as $value) {
$block .= "\x1C\x02".chr($dataset).pack('n', strlen($value)).$value;
}
}
return $block;
}
function xmp(array $description): string
{
return ''
.''
.''
.implode('', $description)
.'';
}
function make(string $file, string $format, ?string $iptc = null, ?string $xmp = null): void
{
$image = new Imagick;
$image->newImage(64, 48, new ImagickPixel('#4a6fa5'), $format);
$image->setImageFormat($format);
if ($iptc !== null) {
$image->setImageProfile('iptc', $iptc);
}
if ($xmp !== null) {
$image->setImageProfile('xmp', $xmp);
}
$image->writeImage($file);
$image->clear();
echo "written: {$file}\n";
}
// 1. Kamera-JPEG mit klassischem IPTC (Credit, By-line, Copyright).
make("{$dir}/camera-iptc.jpg", 'jpeg', iptcBlock([
110 => 'Musterfirma GmbH / Anna Beispiel',
80 => 'Anna Beispiel',
116 => '© 2026 Musterfirma GmbH',
]));
// 2. JPEG mit XMP: KI-generiert (volle IPTC-URI) und Credit als Element.
make("{$dir}/xmp-ai-generated.jpg", 'jpeg', null, xmp([
'http://cv.iptc.org/newscodes/digitalsourcetype/trainedAlgorithmicMedia',
'KI-Bild / Musterfirma',
]));
// 3. JPEG mit XMP algorithmicallyEnhanced (Kurzform) und dc:creator-Liste.
make("{$dir}/xmp-enhanced.jpg", 'jpeg', null, xmp([
'algorithmicallyEnhanced',
'Max Mustermann',
]));
// 4. PNG ohne Metadaten.
make("{$dir}/plain.png", 'png');
// 5. WebP mit XMP als Attribute (digitalCapture, dc:rights).
make("{$dir}/webp-capture.webp", 'webp', null, xmp([
'digitalCapture',
'© Beispiel AG',
]));
// 6. Beschädigte Datei: JPEG-Header, dann Müll.
file_put_contents("{$dir}/broken.jpg", "\xFF\xD8\xFF\xE0".random_bytes(200));
echo "written: {$dir}/broken.jpg\n";