$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";