Using EXIF (IPTC) metadata as tags in the panel

I’m making a system of tags for a website;
In fact i’m tagging my pictures in Lightroom and the data is then exported as metadata in the picture.

Is there a way I can automatically retrieve the metadata in the file to use it in kirby in a tag field?

Also, I’m away of the objet $exif but I can’t seem to retrieve the tags of an image

Image

Thanks.

Those keywords are most probably store in IPTC, not in EXIF.

PHP has a function to parse IPCT data: PHP: iptcparse - Manual

Yeah, thank you very much,
altough, i’m not able to use it dynamically to apply the keywords to my HTML data-metadata-tag=""

I don’t really know how to retrieve that that here. And as soon as I try to make it dynamic I’m facing that error :
exif_read_data(): Unable to open file in Kirby. I feel it has something to do with the media generated?

here is the bit of code i’m using:

<?php
        $imageurl = $image->url();
        echo $imageurl;

        $exif = exif_read_data($imageurl, 'IFD0');
        echo $exif === false ? "No header data found.<br />\n" : "Image contains headers<br />\n";

        $exif = exif_read_data($imageurl, 0, true);

        foreach ($exif as $key => $section) {
          foreach ($section as $name => $val) {
            echo "$key.$name: $val<br />\n";
          }
        }
?>

If it’s stored in Exif data you can use

$exifData = $image->exif();
dump($exifData);

exif_read_data() needs a path to a file, not a url

Alright, I managed to use the tags from th keyword metadata of my jpg file.

<img alt="<?= $image->caption() ?>" data-meta="    
<?php
        $imageurl = $image->root();
        $size = getimagesize($imageurl, $info);
        if (isset($info['APP13'])) {
          $iptc = iptcparse($info['APP13']);
          $keywords = '';
          $keywordcount = count($iptc["2#025"]);
          for ($i = 0; $i < $keywordcount; $i++) {
            $keywords .= $iptc['2#025'][$i] . ', ';
          }
          $keywords = rtrim($keywords, ', ');
          echo $keywords;
        }


?>"
>

What I would like to do now, is to use the fetched keywords (from the metadata) in my panel with the tag field. It will be automatically filled and expandable.
Is there a way I can do that?
Thanks! :slight_smile:

You could achieve this via a file.upload:after hook. In your hook, extract the metadata from the file and then use $file->update() to update the file meta data (in the Kirby sense of the word).

alright,
this post quite helped so far and seem to be doing what I want to achieve.
My newbie question would be that I don’t know where to use this plugin code?

<?php
// Get keywords from IPTC data
function iptc_keywords($image) {
    $size = getimagesize($image->url(), $info);
    if(isset($info['APP13'])){
        $iptc = iptcparse($info['APP13']);

        // Get keywords
        $keywords = '';
        $keywordcount = count($iptc["2#025"]);
        for ($i=0; $i < $keywordcount; $i++) { 
            $keywords .= $iptc['2#025'][$i].', ';
        }
        $keywords = rtrim($keywords,', ');

        return $keywords;
    }
};

kirby()->hook(['panel.file.upload'], function($image) {
  if ($image->type() == 'image') {
    
    // Get date created from exif data
	$datecreated = $image->exif()->timestamp();
	// Get keywords via function
	$keywords = iptc_keywords($image);

	// Update image metadata
	$image->update(array(
		'date' => $datecreated,
		'tags' => $keywords
	));
  }
});

Thanks :slight_smile:

Hooks can be registered in the config or in a plugin’s index.php:

You can find the plugin basics here: Plugin Basics | Kirby CMS

Alright,
Thanks a lot texnixe,
I managed to make something that can work somehow…

'hooks' => [
    'file.create:after' => function ($image) {


      if ($image->type() == 'image') {

        // Get date created from exif data
        $datecreated = $image->exif()->timestamp();
        // Get keywords via function
        function iptc_keywords($image)
        {
          if (isset($info['APP13'])) {
            $iptc = iptcparse($info['APP13']);

            // Get keywords
            $keywords = '';
            $keywordcount = count($iptc["2#025"]);
            for ($i = 0; $i < $keywordcount; $i++) {
              $keywords .= $iptc['2#025'][$i] . ', ';
            }
            $keywords = rtrim($keywords, ', ');

            return $keywords;
          }
        };

        $keywords = iptc_keywords($image);

        // Update image metadata
        $image->update(array(
          'date' => $datecreated,
          'tags' => $keywords
        ));
      }
    }
  ],

There is still something that I can’t understand, it seems that the throw new Exception($image);
is throwing this error : Exception::__construct(): Passing null to parameter #1 ($message) of type string is deprecated
telling me that $image is null.

The variable must be called $file, the hooks use named params!

Oh yeah, thanks, I was using this bits of code from 2018 that was made for kirby 2. Haha.

here is the completly updated hook if needed:

  'hooks' => [
    'file.create:after' => function ($file) 

      if ($file->type() == 'image') {

        // Get date created from exif data
        $datecreated = $file->exif()->timestamp();
        // Get keywords via function
        function iptc_keywords($file)
        {
          getimagesize($file->root(), $info);
          if (isset($info['APP13'])) {
            $iptc = iptcparse($info['APP13']);

            // Get keywords
            $keywords = '';
            $keywordcount = count($iptc["2#025"]);
            for ($i = 0; $i < $keywordcount; $i++) {
              $keywords .= $iptc['2#025'][$i] . ', ';
            }
            $keywords = rtrim($keywords, ', ');

            return $keywords;
          }
        };

        $keywords = iptc_keywords($file);

        // Update image metadata
        $file->update(array(
          'date' => $datecreated,
          'tags' => $keywords
        ));
      }
    }
  ],

:slight_smile:

1 Like