Keeping or writing EXIF,IPTC... data on image resize

There are some posts around on this one, none conclusive for me or too old, like this one.

A client wants to have a copyright text in their images EXIF or IPTC metadata.

Either the client adds this on image creation, then kirby respects it when thumb’ing it (which does not seem to be the case at least here locally with GD )

OR

I write the metadata programatically when thumb’ing the image (although not sure where, in the template itself when calling resize or similar?)

What would be a reccomended, plausible approach here to achieve this ?

Thank you

I would also love to know how to do this on image resize.

If you want to add EXIF data to Kirby’s file metadata, then I would do this using a hook on image upload. There is no hook to hook into image thumbing.

As regards the im driver, setting the strip option to false in thumb options should preserve EXIF data.

1 Like

I’d like the metadata to be preserved when cropping or resizing images via the thumb driver and added the following into config.php:

return [
  'thumbs' => [
    'driver' => 'im',
    'strip' => false,
  ]
];

Unfortunately, it does not work. The metadata is still removed. And yes: I deleted the media folder in between. :wink:

I use the current Kirby version 3.6.2. Do you have any other ideas what I can do?

There is no strip option you could use in the config.

strip is still applied to png files, but not to other files as on older versions of Kirby.

What file types have you tested?

Also, when resizing, Kirby uses ImageMagicks -thumbnail CLI option, which removes more data than -resize: ImageMagick – Command-line Options

If you want to preserve as much data as possible, you might want to create a custom driver based off the ImageMagick driver.

I tested JPG files. On a website for a photographer I want to preserve the copyright metadata in the photos. Can this only be achieved via a custom thumb driver?

Kirby removes metadata for security reasons, that’s why I think that you need a custom driver.

If I were you, I’d experiment on the command line to see what ImageMagick settings preserve the data you need.

Creating a custom driver with those settings is not a big deal, after all.

Thanks for the hint! A custom thumb driver would be nothing more than a plugin, right? Then I’ll try that.

you can re-apply exif meta data like so…
https://www.php.net/manual/en/function.iptcembed.php#113877

so if you encounter a thumb that does not have exif meta data, then go to the source image and re-apply that to the thumb. that might be easier than a custom driver.

if (!$thumb->exif() || empty($thumb->exif()->data()) {
   if ($thumb->original()->exif() && !empty($thumb->original()->exif()->data())) {
        \transferIptcExif2File($thumb->original()->root(), $thumb->root());
   }
}
1 Like

This could be a quick fix, thank you! (In the long run, it would probably be better to develop a plugin, as in my projects copyright metadata in images usually needs to be preserved.) Can you maybe help me one step further and tell me how exactly I can apply your code snippet?

Here the code snippet from my template in which the thumb is created:

<?php if($image = $page->images()->sortBy('sort', 'asc')->first()): ?>
    <img src="<?= $image->crop(800, 600)->url() ?>">
<?php endif ?>

the crop() returns a thumb object you can add more logic based on that var.

$thumb = $image->crop(800, 600);

So I tried the following:

<?php if($thumb = $item->images()->sortBy('sort', 'asc')->first()->crop(800, 600)): ?>
    
    <?php if(!$thumb->exif() || empty($thumb->exif()->data()) {
      if ($thumb->original()->exif() && !empty($thumb->original()->exif()->data())) {
        \transferIptcExif2File($thumb->original()->root(), $thumb->root());
      }
    } ?>

   <img src="<?= $thumb->url() ?>">

<?php endif ?>

This issues a syntax error – unexpected token “{” – in line 3.

sorry about the confusion. you can not mix if statements terminated with : and {. but since you will be using the exif copy a few times it might be best to put it in a custom filemethod.

site/plugins/exit/index.php

<?php

// TODO: copy and paste the transferIptcExif2File function from the link to php.net above.

Kirby::plugin('exif/plugin', [
    'fileMethods' => [
        'transferIptcExif2File' => function () {
            if(!$this->exif() || empty($this->exif()->data()) {
              if ($this->original()->exif() && !empty($this->original()->exif()->data())) {
                \transferIptcExif2File($this->original()->root(), $this->root());
              }
            }
            return $this;
        }
    ]
]);

and call it like that

<?php if($thumb = $item->images()->sortBy('sort', 'asc')->first()->crop(800, 600)): ?>
   <img src="<?= $thumb->transferIptcExif2File()->url() ?>">
<?php endif ?>

Thanks! I followed your steps.

Side note: I think in your code snippet a closing “)” was missing at line 8:

<?php

// Here I’ve inserted the transferIptcExif2File function from https://www.php.net/manual/en/function.iptcembed.php#113877

Kirby::plugin('exif/plugin', [
    'fileMethods' => [
        'transferIptcExif2File' => function() {
            if(!$this->exif() || empty($this->exif()->data())) {
              if ($this->original()->exif() && !empty($this->original()->exif()->data())) {
                \transferIptcExif2File($this->original()->root(), $this->root());
              }
            }
            return $this;
         }
    ]
]);

Unfortunately, it does not work. The image is not rendered:

<img src="">

The problem here is that $thumb is not a file object but a FileVersion object, so calling a file method will not work. You would have to implement this as a normal function.

1 Like

@texnixe . thanks for spotting my error.
@Erdgeschoss you can use the original file and forward the thumb to a filemethod. something like that…

Kirby::plugin('exif/plugin', [
    'fileMethods' => [
        'transferIptcExif2File' => function($thumb) {
            if(!$thumb->exif() || empty($thumb->exif()->data())) {
              if ($thumb->original()->exif() && !empty($thumb->original()->exif()->data())) {
                \transferIptcExif2File($thumb->original()->root(), $thumb->root());
              }
            }
            return $thumb;
         }
    ]
]);
<?php 
$file = $item->images()->sortBy('sort', 'asc')->first();
if($thumb = $file->crop(800, 600)): ?>
   <img src="<?= $file->transferIptcExif2File($thumb)->url() ?>">
<?php endif ?>

@bnomei, thank you, that works now!

For not to have to adapt code snippets in a lot of templates, I have nevertheless created a custom thumb driver plugin as @texnixe suggested, which seems to work at first impression. For that I’ve copied and adapted ImageMagick.php from Kirby’s Darkroom:

  • I removed the command strip and
  • replaced the command thumbnail (because it comes with an implied strip operation) by resize.
2 Likes