[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