Automatic resize images on upload via hook in Kirby 3

Hey all,

in Kirby 2 i had this hook working to automatically resize images on upload. However i cannot get this to work in Kirby 3. Is this still possible? Does anybody know how to do it?

Kirby 2 Code below:

kirby()->hook('panel.file.upload', 'resizeImage');
kirby()->hook('panel.file.replace', 'resizeImage');

function resizeImage($file) {
  // set a max. dimension
  $maxDimension = 850;
  try {
    // check file type and dimensions
    if ($file->type() == 'image' and ($file->width() > $maxDimension)) {

      // get the original file path
      $originalPath = $file->dir() . '/' . $file->filename();
      // create a thumb and get its path
      $resizedImage = $file->resize($maxDimension,null,80);
      $resizedPath = $resizedImage->dir() . '/' . $resizedImage->filename();
      // replace the original image with the resized one
      copy($resizedPath, $originalPath);
      unlink($resizedPath);
      }
  } catch (Exception $e) {
      return response::error($e->getMessage());
  }
}

You can use this plugin: https://github.com/medienbaecker/kirby-autoresize

…or look at the hook source code and do it youself :slight_smile:

2 Likes

I’ve modified this to use it with height as well. Also added quality.

<?php
Kirby::plugin('medienbaecker/autoresize', [
  'options' => [
    'maxHeight' => 2880,
    'maxWidth' => 2880
  ],
  'hooks' => [
    'file.create:after' => function ($file) {
      if ($file->isResizable()) {
        if ($file->height() > option('medienbaecker.autoresize.maxHeight') || $file->width() > option('medienbaecker.autoresize.maxWidth')) {
          try {
            kirby()->thumb($file->root(), $file->root(), [
              'height' => option('medienbaecker.autoresize.maxHeight'),
              'width' => option('medienbaecker.autoresize.maxWidth'),
              'quality' => 80
            ]);
          } catch (Exception $e) {
            throw new Exception($e->getMessage());
          }
        }
      }
    },
    'file.replace:after' => function ($newFile, $oldFile) {
      kirby()->trigger('file.create:after', $newFile);
    }
  ]
]);

Now I want to skip if the file size is less than 400kb, something like:

if ($file->size() > 400kb && ($file->height() > option('medienbaecker.autoresize.maxHeight') || $file->width() > option('medienbaecker.autoresize.maxWidth')))

Is it possible to check the size of the file? :thinking:

And by the way, great hook @thguenther!!

This is working :smiley:

if ($file->size() > 1048576 && ($file->height() > option('medienbaecker.autoresize.maxHeight') || $file->width() > option('medienbaecker.autoresize.maxWidth')))

Edit:
I saved some PNGs in photoshop at around 2.6mb and with 'quality' => 80 it came out at 2.9mb :sweat_smile: need to test this more.

I find β€œquality” to work great with jpg but not so much with png.

I saved one png image at around 2.6mb and optimized it down to 1mb with tinypng. I then uploaded it to kirby with my hook quality at 70. The file came out at 2.9mb.

:point_right: This might be super duper over-complicated but is there a way to compare the original file size to the new one and if the file size of the new one is greater than the original, keep the original.