sRGB conversion and resize upon upload of images

I used a slightly modified version of the panel with this post file upload hook to enable automatic conversion of images upon upload. Use my plugin ImageConverter for conversion.

c::set('panel.upload.post', function($file, $uploadData) {

if ($file->type() == 'image') {
$image = new ImageConverter($file, array(
  'tosRGB' => true,
));
$image->process();
}

});

To make plugins available to the panel use the following site.php file, like described in the Kirby Docs.

<?php

$kirby = kirby();

// make plugins available for panel
$kirby->plugins();
3 Likes

What happens if I use the same name, does it replace the original?
Most CMSes store the uploaded image, even when itā€™s a massive 24 or 36 MP photo. In most cases we only need smaller ones so storing a 2000x2000 or smaller one makes sense (and would avoid the preview limit issue we have at the moment).

Yes. The default method replaces the original and fixes the preview limit issue, because such big images are not necessary most of the time.

You can switch this behaviour with the filename-option:

$image = new ImageConverter($image, array(
  'filename' => '{name}_resized.{extension}',
));
$image->process();

Thanks for this. Iā€™m looking for a way to generate several resized versions of my images on upload to provide them for a responsive design. First one thing, can I execute the image converter several times to produce the resized copies at different settings?

Furthermore, I couldnā€™t get the image converter to work with the upload hook. (I tried just calling the $image->process(); on page-load which worked, so the plugin seems to be set up correctly)

For the upload solution, I added the following at the end of my config.php:

  c::set('panel.upload.post', function($file, $uploadData) {

	if ($file->type() == 'image') {
		$image = new ImageConverter($file, array(
		  'width' => 6000,
		  'height' => 6000,
		  'upscale' => false,
		  'quality' => 100,
		  'filename' => '{name}_resized.{extension}',
		));
		$image->process();
	}

});

Then I created a site.php in my root folder (next to the index.php) with your code:

<?php

$kirby = kirby();

// make plugins available for panel
$kirby->plugins();

If I upload an image now, I can only find the original upload and no _resized version next to it. Do you know how to solve this?

Thanks!

I havenā€™t tried this yet, but I think executing the ImageConverter several times should work.

The upload hook is not officially part of panel core, you must patch it according to this pull request:

After this it should work.

Thanks, it works well now, also to execute the image converter several times.
Is it possible to store the resized versions in a subfolder (like ā€œpagefolder/rezised/ā€)? This way, the files section of a page wouldnā€™t get too crowded.

Yes this is possible with the following code, where you move the file after conversion:

c::set('panel.upload.post', function($file, $uploadData) {

  if ($file->type() == 'image') {
    $image = new ImageConverter($file, array(
      'tosRGB' => true,
      'width' => 1024,
      'height' => 1024,
    ));
    $image->process();

    $destination = $file->dir() . DS . 'subfolder';
    dir::make($destination);
    $file->move($destination . DS . $file->filename());
  }

});
1 Like

Thanks, there is one problem. This script moves the file properly, but if I change the filename via 'filename' => '{name}_resized.{extension}', it moves the original file, but not the resized one. I would like to keep the original in place and move all the resized versions to the subfolder.

Wouldnā€™t it be easiest to directly save the new versions into a subfolder by modifying the plugin.I was trying to do so and just extended the default ā€œurlā€ and ā€œrootā€ with a subfolder like this:

$subfolder = 'resized'
static::$defaults['url'] = $this->source->url() . '/' . $subfolder;
static::$defaults['root'] = $this->source->dir() . DS . $subfolder;

This didnā€™t change anything and the new files are still in the same directory and this also goes kind of beyond my horizon. Anyonw knows the easiest solution for this?

You are right. :smile:
This would be simpler. You must pass the root and url to the ImageConverter as parameter, because the defaults get overwritten by the given SourceImage to place the result per default into the same folder.

So you have to do something like this:

$image = new ImageConverter($file, array(
  'url' => $file->dir() . '/' . 'resized',
  'root' => $file->dir() . DS . 'resized',
  'tosRGB' => true,
  'width' => 1024,
  'height' => 1024,
));
$image->process();

Okay, now, I have the plugin running with the Upload hook and creating 8 different version of each upload, works well, thanks!

Is there a possibility to crop the image in a certain ratio. Letā€™s say, I have a maximum with 1200 (w) x 1600 (h) so the ratio is 12:16 and I would like to get the image automatically cropped to 9:16, so to 900 (w) x 1600 (h)?
(The crop could happen on the left and right side equally)

Thanks!

Does the plugin use ImageMagick as a driver, if I have it set up like this in my config.php?

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

In the thumbs.php I can see different settings for GD or IM, but in the plugin-file, I couldnā€™t find any.

Thanks!

Of course, you can use the Kirby Toolkit dimensions class and some calculations to find the right dimensions and pass them to the ImageConverter. :wink:

The plugin uses always ImageMagick as the Driver because only ImageMagick can handle color profiles. It uses a direct system call instead of PHP Imagick.

Hello again. I|m having some issues with uploading above certain image dimensions. If I try uploading an image with the dimensions 3280 x 4928 px, the upload outputs the error message: ā€œInvalid API methodā€. Uploading a downsized version of the same image with 2172 x 3263 px works well. It seems, that the file size doesnā€™t matter. (if I compress the bigger dimensions to a smaller filesize than the smaller dimensions, the bigger dimensions still fail to upload)

Is there a restriction to max. dimensions?

Thanks for any help!

My info.php says:

upload_max_filesize: 32M
post_max_size: 48M
memory_limit: 128M

Here the upload hook of my my config.php:

c::set('panel.upload.post', function($file, $uploadData) {

		$fileurl = $file->url();
		$filedir = $file->dir();
		$original_fileurl = $fileurl . '/' . 'original-img';
		$original_filedir = $filedir . DS . 'original-img';
		$resized_fileurl = $fileurl . '/' . 'resized-img';
		$resized_filedir = $filedir . DS . 'resized-img';
		$resized_quality = 90;

	//!!Upload hook only for images!
		if ($file->type() == 'image') {

			$imageconvert1 = new ImageConverter($file, array(
				//For image 480 x 1000 (FullWidth)
				'url' => $resized_fileurl,
				'root' => $resized_filedir,
				'width' => 480,
				'height' => 1000,
				'upscale' => false,
				'quality' => $resized_quality,
				'filename' => '{name}_bah_480x1000.{extension}',
				'autoOrient' => true,
			));

			$imageconvert1_x2 = new ImageConverter($file, array(
				//For image 800 x 600 (FullWidth) @2X
				'url' => $resized_fileurl,
				'root' => $resized_filedir,
				'width' => 1600,
				'height' => 1200,
				'upscale' => false,
				'quality' => $resized_quality,
				'filename' => '{name}_bah_480x1000_@2x.{extension}',
				'autoOrient' => true,
			));

			$imageconvert2 = new ImageConverter($file, array(
				//For image 1024 x 768 (FullWidth)
				'url' => $resized_fileurl,
				'root' => $resized_filedir,
				'width' => 1024,
				'height' => 768,
				'upscale' => false,
				'quality' => $resized_quality,
				'filename' => '{name}_bah_1024x768.{extension}',
				'autoOrient' => true,
			));

			$imageconvert2_x2 = new ImageConverter($file, array(
				//For image 1024 x 768 (FullWidth)
				'url' => $resized_fileurl,
				'root' => $resized_filedir,
				'width' => 2048,
				'height' => 1536,
				'upscale' => false,
				'quality' => $resized_quality,
				'filename' => '{name}_bah_1024x768_@2x.{extension}',
				'autoOrient' => true,
			));

			$imageconvert3 = new ImageConverter($file, array(
				//For image 1280 x 960 (2/3-Width)
				'url' => $resized_fileurl,
				'root' => $resized_filedir,
				'width' => 960,
				'height' => 1080,
				'upscale' => false,
				'quality' => $resized_quality,
				'filename' => '{name}_bah_960x1080.{extension}',
				'autoOrient' => true,
			));

			$imageconvert3_x2 = new ImageConverter($file, array(
				//For image 1024 x 768 (FullWidth)
				'url' => $resized_fileurl,
				'root' => $resized_filedir,
				'width' => 1920,
				'height' => 2160,
				'upscale' => false,
				'quality' => $resized_quality,
				'filename' => '{name}_bah_960x1080_@2x.{extension}',
				'autoOrient' => true,
			));
			
			$imageconvert4 = new ImageConverter($file, array(
				//For image 1920 x 1440 (2/3-Width), as DEFAULT IMAGE!!
				'url' => $fileurl,
				'root' => $filedir,
				'width' => 1280,
				'height' => 1440,
				'upscale' => false,
				'quality' => $resized_quality,
				'filename' => '{name}_bah.{extension}',
				'autoOrient' => true,
			));

			$imageconvert4_x2 = new ImageConverter($file, array(
				//For image 1920 x 1440 (2/3-Width), as DEFAULT IMAGE!! @2x
				'url' => $resized_fileurl,
				'root' => $resized_filedir,
				'width' => 2560,
				'height' => 2880,
				'upscale' => false,
				'quality' => $resized_quality,
				'filename' => '{name}_bah_@2x.{extension}',
				'autoOrient' => true,
			));
			
			$imageconvert5 = new ImageConverter($file, array(
				//For image anything above 1920 x 1440
				'url' => $resized_fileurl,
				'root' => $resized_filedir,
				'width' => 1800,
				'height' => 1920,
				'upscale' => false,
				'quality' => $resized_quality,
				'filename' => '{name}_bah_1800x1920.{extension}',
				'autoOrient' => true,
			));
			
			$imageconvert5_x2 = new ImageConverter($file, array(
				//For image 1920 x 1440 (2/3-Width), as DEFAULT IMAGE!!
				'url' => $resized_fileurl,
				'root' => $resized_filedir,
				'width' => 3600,
				'height' => 3840,
				'upscale' => false,
				'quality' => $resized_quality,
				'filename' => '{name}_bah_1800x1920_@2x.{extension}',
				'autoOrient' => true,
			));

			//!!Create ORIGINAL directory, IF doesn't exist
				if (!file_exists($original_filedir)) {
				    mkdir($original_filedir, 0777, true);
				}

			//!!Create RESIZED directory, IF doesn't exist
				if (!file_exists($resized_filedir)) {
				    mkdir($resized_filedir, 0777, true);
				}

			//!!Process the set up conversions
				$imageconvert1->process();
				$imageconvert1_x2->process();
				$imageconvert2->process();
				$imageconvert2_x2->process();
				$imageconvert3->process();
				$imageconvert3_x2->process();
				$imageconvert4->process();
				$imageconvert4_x2->process();
				$imageconvert5->process();
				$imageconvert5_x2->process();

			//!!At the end, move original upload to ORIGINAL-folder
				$file->move($original_filedir . DS . $file->filename());
		
		}
	});

As i know there is only a restriction according to the memory_limit.
Try using a higher memory_limit.

Is there an updated version of this solution with the new Kirby panel hooks?

The plugin stays the same when using the new panel hooks. Only the hook registration changes and you donā€™t have to change kirby core for this anymore, because of the following hook: (should work, not tested)

kirby()->hook('panel.file.upload', function($file) { {

if ($file->type() == 'image') {
$image = new ImageConverter($file, array(
  'tosRGB' => true,
));
$image->process();
}

});