[wp-trac] [WordPress Trac] #55535: Pre-populate Image Alt Text field with IPTC Photo Metadata Standard Alt Text
WordPress Trac
noreply at wordpress.org
Fri Jan 27 16:47:38 UTC 2023
#55535: Pre-populate Image Alt Text field with IPTC Photo Metadata Standard Alt
Text
-------------------------+----------------------------
Reporter: eatingrules | Owner: joedolson
Type: enhancement | Status: accepted
Priority: normal | Milestone: 6.2
Component: Media | Version:
Severity: minor | Resolution:
Keywords: needs-patch | Focuses: accessibility
-------------------------+----------------------------
Comment (by pbiron):
thanx @brendanquinn.
For everyone, here's the embedded XMP from [attachment:"Tired Spongebob
Meme.jpg"] (with `...` meaning that parts have been elided for clarity):
{{{#!xml
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 7.0-c000
1.000000, 0000/00/00-00:00:00">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
...
>
...
<Iptc4xmpCore:ExtDescrAccessibility>
<rdf:Alt>
<rdf:li xml:lang="x-default">Spongebob leans on his hand as if to
balance or stabilize himself. He's naked, not wearing his usual square
pants, and he's looking off to one side with his brow pulled up, looking
completely exhausted. Both of his cheeks are puffed out as he exhales from
a small opening in his mouth, like he's out of breath and trying to
recover. </rdf:li>
<rdf:li xml:lang="en">Spongebob leans on his hand as if to balance or
stabilize himself. He's naked, not wearing his usual square pants, and
he's looking off to one side with his brow pulled up, looking completely
exhausted. Both of his cheeks are puffed out as he exhales from a small
opening in his mouth, like he's out of breath and trying to recover.
</rdf:li>
</rdf:Alt>
</Iptc4xmpCore:ExtDescrAccessibility>
<Iptc4xmpCore:AltTextAccessibility>
<rdf:Alt>
<rdf:li xml:lang="x-default">Meme. Spongebob Squarepants leans
against the wall of an undersea cave, puffing out his cheeks with a tired
and put-upon expression. Caption: Me after I put the fitted sheet on the
bed by myself.</rdf:li>
<rdf:li xml:lang="en">Meme. Spongebob Squarepants leans against the
wall of an undersea cave, puffing out his cheeks with a tired and put-upon
expression. Caption: Me after I put the fitted sheet on the bed by
myself.</rdf:li>
</rdf:Alt>
</Iptc4xmpCore:AltTextAccessibility>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
}}}
And here's some working code to extract the `AltTextAccessibility` from
the XMP, which builds on what @brendanquinn posted and is more complete.
I through this together pretty quickly, and I'm sure it can be improved
upon.
{{{#!php
<?php
$jpeg_contents = file_get_contents( $file );
// Find the start and end positions of the XMP metadata
$xmp_start = strpos( $jpeg_contents, '<x:xmpmeta' );
$xmp_end = strpos( $jpeg_contents, '</x:xmpmeta>');
// Extract the XMP metadata from the JPEG contents
$xmp_data = substr( $jpeg_contents, $xmp_start, $xmp_end - $xmp_start + 12
);
// Parse the XMP metadata using DOMDocument
$doc = new DOMDocument();
$doc->loadXML( $xmp_data );
// Instantiate an XPath object, used to extract portions of the XMP.
$xpath = new DOMXPath( $doc );
// Register the relevant XML namespaces.
$xpath->registerNamespace( 'x', 'adobe:ns:meta/' );
$xpath->registerNamespace( 'rdf', 'http://www.w3.org/1999/02/22-rdf-
syntax-ns#' );
$xpath->registerNamespace( 'Iptc4xmpCore',
'http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/' );
$node_list = $xpath->query(
'/x:xmpmeta/rdf:RDF/rdf:Description/Iptc4xmpCore:AltTextAccessibility' );
if ( $node_list && $node_list->count() ) {
// Get the alt text accessibility alternative most appropriate for
the site language.
$node = $node_list->item( 0 );
// Get the site's locale.
$locale = get_locale();
// There are 3 possibilities:
//
// 1. there is an rdf:li with an exact match on the site locale
// 2. there is an rdf:li with a partial match on the site locale
(e.g., site locale is en_US and rdf:li has @xml:lang="en")
// 3. there is an rdf:li with an "x-default" lang.
//
// we evaluate them in that order, stopping when we have a match.
$value = $xpath->evaluate( "string( rdf:Alt/rdf:li[ @xml:lang =
'{$locale}' ] )", $node );
if ( ! $value ) {
$value = $xpath->evaluate( 'string( rdf:Alt/rdf:li[
@xml:lang = "' . substr( $locale, 0, 2 ) . '" ] )', $node );
if ( ! $value ) {
$value = $xpath->evaluate( 'string(
rdf:Alt/rdf:li[ @xml:lang = "x-default" ] )', $node );
}
}
}
}}}
Also note that it's possible that there are multiple `<x:xmpmeta>`
embedded with a given image, and the above code doesn't handle that case.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/55535#comment:23>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list