One of the best services for compressing images is https://tinypng.com/. Each month you can compress up to 500 images free. If you need to compress more images each month it costs, but it’s at a low price ($0.009 per image).
Compressing images is good for loading time, better user experience and SEO.
Tinypng compressor plugin - For Kirby
A good thing is that there is an Tinypng API. Another great things is that Kirby now support hooks!
Code
Save it as /tinypng/tinypng.php in your plugin folder.
I’m not sure if it will help on the thumbnail folder.
I just checked with a 11.1 KB JPEG image (200x200), and TinyJPG saved exactly 0 bytes…
However, I did write a Perl script that uses the API to convert images, and I can whip up something that will process all images in a folder if you want…
Here you go.
This script will convert all .jpg & .png files in the given directory.
If you run it with ‘overwrite’ as second parameter, it will do just that
It’s a bit sparse as far as feedback goes: If all goes will it will be silent for a while, and then return the prompt.
#!perl
#
# Tiny PNG/Tiny JPG API interface
#
use strict;
use LWP;
use constant API_KEY => '<INSERT API KEY HERE>';
use constant API_URL => 'https://api.tinify.com/shrink';
main();
sub main {
my $input = $ARGV[0];
my $overwrite = $ARGV[1];
my $save_prefix = 'tiny_';
if ($overwrite eq 'overwrite') {
$save_prefix = '';
}
unless ($input) {
die "\nUsage: $0 <input dir> ['overwrite']\nIf 'overwrite' is added, the source files will be overwritten\n\n";
}
unless(-d $input) {
die "\nDirectory $input not found!\n\n";
}
my @files = read_dir($input);
foreach my $file (@files) {
my $data = slurp_file($input . '/' . $file);
my $agent = new LWP::UserAgent;
my $request = new HTTP::Request(POST => API_URL);
$request->authorization_basic('api',API_KEY());
$request->content($data);
my $response = $agent->request($request);
if ($response->code() eq '201') {
my $result_url = $response->header('Location');
$request = new HTTP::Request(GET => $result_url);
$response = $agent->request($request);
my $result_data = $response->content();
my $output = $input . '/' . $save_prefix . $file;
store_data(file => $output, data => $result_data);
} else {
print "Error " . $response->code() . " while trying to shrink $input\n";
}
}
}
sub read_dir {
my $dir = shift;
opendir(DIR,$dir) or die "Could not open dir $dir! ($!)\n";
my @files = grep { /\.(jpg|png)$/} readdir(DIR);
closedir(DIR);
return @files;
}
sub slurp_file {
my $file = shift;
my $str = "";
local *F;
if (!open (F,"<$file")) {
return(undef);
} else {
local $/ = undef;
$str = <F>;
close(F);
}
return($str);
}
sub store_data {
my %param = @_;
my $data = $param{'data'};
my $output = $param{'file'};
open(OUTFILE,">$output") || die "\nCould not open $output ($@)\n\n";
print OUTFILE $data;
close(OUTFILE);
}