Changing Toolkit Thumbs Drivers: Scale, Crop

I am trying to add more complex scaling, cropping to images generated with toolkit thumbs function. But I am stuck at extending the kirby toolkit.

I want to use json formated settings from this jquery plugin: GitHub - matiasgali/guillotine: jQuery plugin to crop images within an area (fully responsive), allowing to drag (touch support), zoom and rotate.
which looks like this:

  {'scale':0.89,'angle':0,'x':126,'y':611,'w':1600,'h':900}

so I need to change or extend the toolkit thumbs driver functions to support the commands in the following order

  • scaling up by percentage
  • rotating the image (optional)
  • starting at point x/y generate new image with width (w) and height(h)

the values in the data can considered not to be out of bounds. the jquery plugin only generates possible values.

how to I extend the thumbs drivers without loosing update support?
can anyone help me with coding imagemagic commands needed? Resizing or Scaling -- IM v6 Examples

other cropping posts by @Pascalmh and @fanningert

apart from rotation, which i do not need now, the following calls of imagemagick are what i want.

abstract

convert INFILE -gravity NorthWest -resize PERCENT -crop +OFFX+OFFY +repage -extent WIDTHxHEIGHT OUTFILE

example

convert input.jpg -gravity NorthWest -resize 200% -crop +100+200 +repage -extent 100x100 output.jpg

so how do I add this functionality to toolkit thumbs drivers without breaking the ability to update kirby? can I extend the thumbs class and override the function?

INPUT

OUTPUT

CHECK

You can overwrite the im driver from a plugin without changing the core:

thumb::$drivers['im'] = function($thumb) {
  // whatever
};

You can use the existing driver as a template and modify it to do what you need.

thx @lukasbestle but I am still stuck. I verified imagemagick is installed. I added a site/plugin/myplugin with your code example. but it seems it is not loaded. i would have expected to get no image if driver code is empty. but i do get the original image.

i tried some dummy code but still no luck. what am I missing?

<?php
thumb::$drivers['im'] = function($thumb) {
    $command = array();
    $command[] = 'convert';
    $command[] = '"' . $thumb->source->root() . '"';
    $command[] = '-strip -resize 100x100^ -crop 100x100+0+0';
    $command[] = '"' . $thumb->destination->root . '"';
    exec(implode(' ', $command));
};

If you get the original image, it most likely means that your thumbs directory does not exist or is not writable.

it seems it uses GDLib even my server has imagemagick installed. i checked availability of imagemagick using this:

if( extension_loaded('imagick') || class_exists("Imagick") ) { ... }

how does toolkit thumbs code check it? I can not find it.
default value of thumb settings is

    'driver'      => 'im',

but maybe its overwritten somewhere?

edited: found it kirby.php does https://github.com/getkirby/kirby/blob/master/kirby.php#L94

added the following to site/config.php

c::set('thumbs.driver', 'im');

and added a valid dummy code to my thumbs code. edited example above.

$command[] = '-strip -resize 100x100^ -crop 100x100+0+0';

now it seems to work as intended.

Yes, GD has always been the default. :slight_smile:
Great that it works now.

ended up using a custom driver like that

$json = trim($thumb->options['guillotine']); // (string)
$json = str_replace("'", '"', $json); // stored with \' instead of \" in panel <input value="">
$guillotine = str::parse($json, 'json');
$scale = floatval($guillotine['scale']);
$dimensions = clone $thumb->source->dimensions();

$command[] = 'convert';
$command[] = '"' . $thumb->source->root() . '"';
$command[] = '-strip';
$command[] = '-gravity NorthWest';
$command[] = '-resize '.intval($dimensions->width()*$scale).'x'.intval($dimensions->height()*$scale).'^';
$command[] = '-crop '.$guillotine['w'].'x'.$guillotine['h'].'+'.$guillotine['x'].'+'.$guillotine['y'];
$command[] = '+repage';

$command[] = '"' . $thumb->destination->root . '"';
//echo "<!--# ". implode(' ', $command). ' #-->';
exec(implode(' ', $command));
1 Like

since i am using a custom option only. how to I trigger the creation of a new thumb once my values changed?

Once which values change?

within the panel I added a custom field which includes the jquery cropping script. the output of the jquery is saved to the value of that field. then I can hit save in panel. but as far as i can tell the thumb is not regenerated - since the image did not really change, just my cropping data which will be forwarded to thumbs driver.
can i trigger recreation of the thumb based on my changed value?

Please see the settingsIdentifier method of the Thumb class. The values mentioned there are incorporated into the hash that is then used to identify the image. If any of these values change, the thumb is regenerated, otherwise the cached copy is used.

You can however manually set the filename param on the Thumb object to include more custom values. The default is '{safeName}-{hash}.{extension}' and you can change it to be '{safeName}-{hash}-x123y234w123h234.{extension}' for example.

perfect! will do as you suggested.