Batch jpg, jpeg and png image resizer, optimiser and image profiler using ImageMagick convert, OptiPNG, JpegOptim and optional Mozilla MozJPEG, ZopfliPNG and Google Guetzli (work in progress for Guetzli).
- Profiler mode allows you to point the script to a directory of images and for JPG, JPEG and PNG files will profile and gather individual image's information such as image name, width, height, size, colour depth, whether it's a transparent image, image user/group permissions etc. Optionally, you can set
PROFILE_EXTEND='y'
to also display each individual images transparent and background colours. For processing speed, these are disabled by default withPROFILE_EXTEND='n'
. - The profiler runs are logged to directory defined by
LOGDIR='/home/optimise-logs'
so you can use command line tools like grep, awk etc to filter information or diff comparison tools to compare before and after optimisation profile logs. This allows you to double check the optimised and resized images retain their properties you require like image transparency or whether or not image is interlaced/progressive. - Optimisation modes highlighted in examples linked below allow you to batch resize and optimise images as well as convert them to WebP format via tools such as ImageMagick, JpegOptim, OptiPNG and optionally support Mozilla MozJPEG, Google ZopfliPNG and Google Guetzli. Support for GraphicsMagick is still a work in progress though so is not fully supported for all modes of operation.
- By default the resize and optimisation routines will check to see if an original image is transparent and/or is interlaced/progressive and will retain those image properties through the process.
- There are specific optimisation modes which allow for more convenient conversions to WebP format - including automatic generation of a lazy load supported static html gallery displaying side by side, the optimised original versus the WebP converted image as well as Ngnx syntax for WebP conditional serving. You can turn off static html gallery generation via option
GALLERY_WEBP='n'
. - Each optimise run will prompt user to ask if they have backed up their image directory prior to batch optimisation and resizing and is now controlled via variable
UNATTENDED_OPTIMISE='n'
which is set to default. You can skip the backup question prompt for more advanced scripted runs ofoptimise-images.sh
by setting variableUNATTENDED_OPTIMISE='y'
. - Benchmark modes highlighted in example links below, are testing methods coded to work to test the before optimisation profiling + optimisation + after optimisation profiling routines on a preset directory of images.
- Running the script is timed so you get timed completion statistics information so you can measure the speed of profiling, optimisation and conversion.
- System resource usage logging is done via sysstat after each individual image processing so you can use sar command to understand the cpu, memory and disk usage profiles during or after the script runs.
- You can control nice and ionice priorities for the conversion and resize processes via variables
NICEOPT='-n 10'
andIONICEOPT='-c2 -n7'
to either set a higher or lower priority. - profile-age & optimise-age Mode allows you to filter and limit profiling and optimisation of images by image timestamp age.
- optimise-cron & optimise-cron-age Mode for use in cronjob scheduled runs which removes the post-optimisation profile routine run to save time.
- ADD_COMMENT variable optional variable when enabled
ADD_COMMENT='y'
, the script's ImageMagick routine will add to optimised images a comment =optimised
marking optimised images. This will allow subsequent re-runs of script to detect the comment =optimised
and skip re-optimising of the previously optimised image and only optimise unoptimised images. This will speed up the optimisation process on re-runs.
- ImageMagick 6+ or 7+
- CentOS Epel YUM repository
- CentOS/RHEL YUM install for
optipng
&jpegoptim
- Google Butteraugli source installed automatically by
optimise-images.sh
optimise-images.sh
will auto install via source compile if MozJPEG,zopflipng
and/orguetzli
is required
- 24/04/17 Example
- 25/04/17 New Option: Compare Mode
- 26/04/17 New Option: WebP conversion support
- 26/04/17 New Option: WebP conversion + Compare Mode
- 27/04/17 New Option: ImageMagick 7 Custom Install
- 27/04/17 New Option: Benchmark Mode
- 27/04/17 New Option: Benchmark WebP + Compare Mode
- 28/04/17 New Option: Profile Log Only Option
- 29/04/17 Benchmark Compare - All JPG/PNG Compressors
- 30/04/17 New Option: optimise-webp mode
- 30/04/17 New Option: optimise-webp-nginx mode (updated 01/05/17 static gallery added)
- 17/08/17 New Option: profile-age & optimise-age Mode
- 17/08/17 New Option: optimise-cron & optimise-cron-age Mode
- 18/08/17 New Option: ADD_COMMENT variable marker to skip previously optimised images
Example below uses preset selection of images localed in directory /home/nginx/domains/domain.com/public/images
Create directory
mkdir -p /home/nginx/domains/domain.com/public/images
Setup optimise-images.sh
mkdir -p /root/tools
cd /root/tools
git clone --depth=1 https://github.com/centminmod/optimise-images
Usage Options
./optimise-images.sh
./optimise-images.sh {optimise} /PATH/TO/DIRECTORY/WITH/IMAGES
./optimise-images.sh {optimise-age} /PATH/TO/DIRECTORY/WITH/IMAGES
./optimise-images.sh {optimise-cron} /PATH/TO/DIRECTORY/WITH/IMAGES
./optimise-images.sh {optimise-cron-age} /PATH/TO/DIRECTORY/WITH/IMAGES
./optimise-images.sh {optimise-webp} /PATH/TO/DIRECTORY/WITH/IMAGES
./optimise-images.sh {optimise-webp-nginx} /PATH/TO/DIRECTORY/WITH/IMAGES
./optimise-images.sh {profile} /PATH/TO/DIRECTORY/WITH/IMAGES
./optimise-images.sh {profile-age} /PATH/TO/DIRECTORY/WITH/IMAGES
./optimise-images.sh {profilelog} /PATH/TO/DIRECTORY/WITH/IMAGES
./optimise-images.sh {testfiles} /PATH/TO/DIRECTORY/WITH/IMAGES
./optimise-images.sh {install}
./optimise-images.sh {bench}
./optimise-images.sh {bench-compare}
./optimise-images.sh {bench-webp}
./optimise-images.sh {bench-webpcompare}
./optimise-images.sh {bench} all
./optimise-images.sh {bench-compare} all
./optimise-images.sh {bench-webp} all
./optimise-images.sh {bench-webpcompare} all
Google Guetzli Notes
- Guetzli uses a large amount of memory. You should provide 300MB of memory per 1MPix of the input image.
- Guetzli uses a significant amount of CPU time. You should count on using about 1 minute of CPU per 1 MPix of input image.
- When enabled with
GUETZLI='y'
andTESTFILES_MINIMAL='n'
some of the additional sample jpg images are unable to optimise resulting in the following errors as it seems Guetzli is designed to work on high quality image sources which haven't already been compressed i.e. lossless format source images such as PNG google/guetzli#195:
Unsupported input JPEG file (e.g. unsupported downsampling mode).
Please provide the input image as a PNG file.
Variables by default
- sample image downloads are kept minimal with
TESTFILES_MINIMAL='y'
. Large sample set of images to test against are available when setTESTFILES_MINIMAL='n'
- use ImageMagick convert to resize to max resolution
MAXRES='2048'
- with JPG image optimisation with JpegOptim with quality of
IMAGICK_QUALITY='82'
for jpeg/jpg whenJPEGOPTIM='y'
set - with PNG use OPTIPNG quality of
92
meaningpng:compression-level=9
andpng:compression-strategy=2
by default whenOPTIPNG='y'
set. - strip meta-data from images via
STRIP='y'
# control sample image downloads
# allows you to control how many sample images to work with/download
# guetzli testing is very resource and time consuming so working with
# a smaller sample image set would be better
TESTFILES_MINIMAL='y'
# max width and height
MAXRES='2048'
IMAGICK_RESIZE='y'
IMAGICK_JPEGHINT='y'
IMAGICK_QUALITY='82'
IMAGICK_WEBP='n'
IMAGICK_WEBPQUALITY='75'
IMAGICK_WEBPQUALITYALPHA='100'
IMAGICK_WEBPMETHOD='4'
IMAGICK_WEBPLOSSLESS='n'
IMAGICK_WEBPTHREADS='1'
# Quantum depth 8 or 16 for ImageMagick 7
# Source installs
IMAGICK_QUANTUMDEPTH='8'
IMAGICK_SEVEN='n'
IMAGICK_TMPDIR='/home/imagicktmp'
IMAGICK_JPGOPTS=' -filter Triangle -define filter:support=2 -define jpeg:fancy-upsampling=off -unsharp 0.25x0.08+8.3+0.045'
IMAGICK_PNGOPTS=' -define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=2'
IMAGICK_WEBPOPTS=" -define webp:method=${IMAGICK_WEBPMETHOD} -define webp:alpha-quality=${IMAGICK_WEBPQUALITYALPHA} -define webp:lossless=false -quality ${IMAGICK_WEBPQUALITY}"
# strip meta-data
STRIP='y'
# additional image optimisations after imagemagick
# resizing
JPEGOPTIM='y'
GUETZLI='n'
# choose either OPTIPNG or ZOPFLIPNG
OPTIPNG='y'
ZOPFLIPNG='n'
# Speed control
# default is -o2 set 2
OPTIPNG_COMPRESSION='2'
# Guetzli Options
# GUETZLI_JPEGONLY will only optimise original jpeg/jpg
# images and NOT convert png to Guetzli optimised jpgs
# set to = 'n' to convert png as well
GUETZLI_JPEGONLY='y'
GUETZLI_QUALITY='85'
GUETZLI_OPTS='--verbose'
# profile option display fields for transparency color and background color
# disabled by default to speed up profile processing
PROFILE_EXTEND='n'
# comparison mode when enabled will when resizing and optimising images
# write to a separate optimised image within the same directory as the
# original images but with a suffix attached to the end of original image
# file name i.e. image.png vs image_optimal.png
COMPARE_MODE='n'
COMPARE_SUFFIX='_optimal'
# optionally create thumbnails in separate directory
# within image directory and thumbnail width x height
# and thumbnail image format default = .jpg
THUMBNAILS='n'
THUMBNAILS_QUALITY='72'
THUMBNAILS_WIDTH='150'
THUMBNAILS_HEIGHT='150'
THUMBNAILS_FORMAT='jpg'
THUMBNAILS_DIRNAME='thumbnails'
LOGDIR='/home/optimise-logs'
LOGNAME_PROFILE="profile-log-${DT}.log"
LOG_PROFILE="${LOGDIR}/${LOGNAME_PROFILE}"
BENCHDIR='/home/optimise-benchmarks'
GUETZLI_BIN='/opt/guetzli/bin/Release/guetzli'
Populate via testfiles
command option passing the directory /home/nginx/domains/domain.com/public/images
with sample images on the command line
/root/tools/optimise-images/optimise-images.sh testfiles /home/nginx/domains/domain.com/public/images
Output
Downloading sample image files
to /home/nginx/domains/domain.com/public/images
2017-04-27 16:18:46 URL:https://raw.githubusercontent.com/centminmod/optimise-images/master/images/samsung_s7_mobile_1.jpg [2100858/2100858] -> "samsung_s7_mobile_1.jpg" [1]
2017-04-27 16:18:47 URL:https://raw.githubusercontent.com/centminmod/optimise-images/master/images/dslr_canon_eos_m6_1.jpg [207430/207430] -> "dslr_canon_eos_m6_1.jpg" [1]
2017-04-27 16:18:48 URL:https://raw.githubusercontent.com/centminmod/optimise-images/master/images/webp-study-source-firebreathing.png [1206455/1206455] -> "webp-study-source-firebreathing.png" [1]
2017-04-27 16:18:48 URL:https://raw.githubusercontent.com/centminmod/optimise-images/master/images/png24-image1.png [400998/400998] -> "png24-image1.png" [1]
2017-04-27 16:18:49 URL:https://raw.githubusercontent.com/centminmod/optimise-images/master/images/png24-interlaced-image1.png [456949/456949] -> "png24-interlaced-image1.png" [1]
total 4.3M
drwxr-sr-x 2 root nginx 4.0K Apr 27 16:18 .
drwxr-s---. 4 nginx nginx 4.0K Apr 23 06:35 ..
-rw-r--r-- 1 root nginx 203K Apr 27 16:18 dslr_canon_eos_m6_1.jpg
-rw-r--r-- 1 root nginx 392K Apr 27 16:18 png24-image1.png
-rw-r--r-- 1 root nginx 447K Apr 27 16:18 png24-interlaced-image1.png
-rw-r--r-- 1 root nginx 2.1M Apr 27 16:18 samsung_s7_mobile_1.jpg
-rw-r--r-- 1 root nginx 1.2M Apr 27 16:18 webp-study-source-firebreathing.png
Profile original images via script's profile
flag and pass the directory path to the directory containing the images you want to optimise /home/nginx/domains/domain.com/public/images
. This is your baseline to compare resizing and optimisations applied to images using above default variable parameters.
Original images average 1491 pixel width, 1075 pixel height, 92% image quality and 874,438 bytes per image with total size of 4,270 KB.
/root/tools/optimise-images/optimise-images.sh profile /home/nginx/domains/domain.com/public/images
------------------------------------------------------------------------------
image profile
image name : width : height : quality : transparency : image depth (bits) : size : user: group
------------------------------------------------------------------------------
images in /home/nginx/domains/domain.com/public/images
logged at /home/optimise-logs/profile-log-270417-161941.log
------------------------------------------------------------------------------
image : dslr_canon_eos_m6_1.jpg : 1200 : 800 : 90 : False : 8 : 207430 : root : nginx
image : png24-image1.png : 600 : 400 : 92 : False : 8 : 400998 : root : nginx
image : png24-interlaced-image1.png : 600 : 400 : 92 : False : 8 : 456949 : root : nginx
image : samsung_s7_mobile_1.jpg : 4032 : 3024 : 92 : False : 8 : 2100858 : root : nginx
image : webp-study-source-firebreathing.png : 1024 : 752 : 92 : False : 8 : 1206455 : root : nginx
------------------------------------------------------------------------------
Original or Existing Images:
------------------------------------------------------------------------------
| Avg width | Avg height | Avg quality | Avg size | Total size (Bytes) | Total size (KB) |
| --------- | ---------- | ----------- | -------- | ------------------ | --------------- |
| 1491 | 1075 | 92 | 874538 | 4372690 | 4270 |
------------------------------------------------------------------------------
ImageMagick Resource Limits
------------------------------------------------------------------------------
Version: ImageMagick 6.9.8-4 Q16 x86_64 2017-04-25
Resource limits:
Width: 214.7MP
Height: 214.7MP
Area: 67.057GP
Memory: 31.226GiB
Map: 62.4521GiB
Disk: unlimited
File: 196608
Thread: 4
Throttle: 0
Time: unlimited
------------------------------------------------------------------------------
Completion Time: 0.14 seconds
------------------------------------------------------------------------------
Optimise images using optimise
flag and pass the directory path to the directory containing the images you want to optimise /home/nginx/domains/domain.com/public/images
/root/tools/optimise-images/optimise-images.sh optimise /home/nginx/domains/domain.com/public/images
Then use profile
flag again to profile the optimised images.
Optimised images average 1094 pixel width, 778 pixel height, 88% image quality and 476,711 bytes per image with total size of 2328 KB.
/root/tools/optimise-images/optimise-images.sh profile /home/nginx/domains/domain.com/public/images
------------------------------------------------------------------------------
image profile
image name : width : height : quality : transparency : image depth (bits) : size : user: group
------------------------------------------------------------------------------
images in /home/nginx/domains/domain.com/public/images
logged at /home/optimise-logs/profile-log-270417-162213.log
------------------------------------------------------------------------------
image : dslr_canon_eos_m6_1.jpg : 1200 : 800 : 82 : False : 8 : 161086 : root : nginx
image : png24-image1.png : 600 : 400 : 92 : False : 8 : 386063 : root : nginx
image : png24-interlaced-image1.png : 600 : 400 : 92 : False : 8 : 386063 : root : nginx
image : samsung_s7_mobile_1.jpg : 2048 : 1536 : 82 : False : 8 : 256253 : root : nginx
image : webp-study-source-firebreathing.png : 1024 : 752 : 92 : False : 8 : 1194091 : root : nginx
------------------------------------------------------------------------------
Original or Existing Images:
------------------------------------------------------------------------------
| Avg width | Avg height | Avg quality | Avg size | Total size (Bytes) | Total size (KB) |
| --------- | ---------- | ----------- | -------- | ------------------ | --------------- |
| 1094 | 778 | 88 | 476711 | 2383556 | 2328 |
------------------------------------------------------------------------------
ImageMagick Resource Limits
------------------------------------------------------------------------------
Version: ImageMagick 6.9.8-4 Q16 x86_64 2017-04-25
Resource limits:
Width: 214.7MP
Height: 214.7MP
Area: 67.057GP
Memory: 31.226GiB
Map: 62.4521GiB
Disk: unlimited
File: 196608
Thread: 4
Throttle: 0
Time: unlimited
------------------------------------------------------------------------------
Completion Time: 0.08 seconds
------------------------------------------------------------------------------
Side by side comparison of original vs default resized/optimised image profiles using generated log files during profile runs. Originals (left) vs resized/optimised (right)
sdiff -w 180 /home/optimise-logs/profile-log-270417-161941.log /home/optimise-logs/profile-log-270417-162213.log
image : dslr_canon_eos_m6_1.jpg : 1200 : 800 : 90 : False : 8 : 207430 : root : nginx | image : dslr_canon_eos_m6_1.jpg : 1200 : 800 : 82 : False : 8 : 161086 : root : nginx
image : png24-image1.png : 600 : 400 : 92 : False : 8 : 400998 : root : nginx | image : png24-image1.png : 600 : 400 : 92 : False : 8 : 386063 : root : nginx
image : png24-interlaced-image1.png : 600 : 400 : 92 : False : 8 : 456949 : root : ng | image : png24-interlaced-image1.png : 600 : 400 : 92 : False : 8 : 386063 : root : ng
image : samsung_s7_mobile_1.jpg : 4032 : 3024 : 92 : False : 8 : 2100858 : root : ngi | image : samsung_s7_mobile_1.jpg : 2048 : 1536 : 82 : False : 8 : 256253 : root : ngin
image : webp-study-source-firebreathing.png : 1024 : 752 : 92 : False : 8 : 1206455 : | image : webp-study-source-firebreathing.png : 1024 : 752 : 92 : False : 8 : 1194091 :
Use optional ZopfliPNG instead of OptiPNG for png file optimisations
IMAGICK_RESIZE='y'
IMAGICK_QUALITY='82'
# additional image optimisations after imagemagick
# resizing
JPEGOPTIM='y'
GUETZLI='n'
# choose either OPTIPNG or ZOPFLIPNG
OPTIPNG='n'
ZOPFLIPNG='y'
# max width and height
MAXRES='2048'
# strip meta-data
STRIP='y'
Resulting optimised image profiles
/root/tools/optimise-images/optimise-images.sh profile /home/nginx/domains/domain.com/public/images
------------------------------------------------------------------------------
image profile
image name : width : height : quality : transparency : image depth (bits) : size : user: group
------------------------------------------------------------------------------
images in /home/nginx/domains/domain.com/public/images
logged at /home/optimise-logs/profile-log-270417-162455.log
------------------------------------------------------------------------------
image : dslr_canon_eos_m6_1.jpg : 1200 : 800 : 82 : False : 8 : 161086 : root : nginx
image : png24-image1.png : 600 : 400 : 92 : False : 8 : 386195 : root : nginx
image : png24-interlaced-image1.png : 600 : 400 : 92 : False : 8 : 386195 : root : nginx
image : samsung_s7_mobile_1.jpg : 2048 : 1536 : 82 : False : 8 : 256253 : root : nginx
image : webp-study-source-firebreathing.png : 1024 : 752 : 92 : False : 8 : 1184812 : root : nginx
------------------------------------------------------------------------------
Original or Existing Images:
------------------------------------------------------------------------------
| Avg width | Avg height | Avg quality | Avg size | Total size (Bytes) | Total size (KB) |
| --------- | ---------- | ----------- | -------- | ------------------ | --------------- |
| 1094 | 778 | 88 | 474908 | 2374541 | 2319 |
------------------------------------------------------------------------------
ImageMagick Resource Limits
------------------------------------------------------------------------------
Version: ImageMagick 6.9.8-4 Q16 x86_64 2017-04-25
Resource limits:
Width: 214.7MP
Height: 214.7MP
Area: 67.057GP
Memory: 31.226GiB
Map: 62.4521GiB
Disk: unlimited
File: 196608
Thread: 4
Throttle: 0
Time: unlimited
------------------------------------------------------------------------------
Completion Time: 0.08 seconds
------------------------------------------------------------------------------
Focus on png file optimisations for select files not much difference.
For OptiPNG - averages 1224 width, 1022 height, 92 quality, 268,831 KB per image
image : png24-image1.png : 600 : 400 : 92 : False : 8 : 386063 : root : nginx
image : png24-interlaced-image1.png : 600 : 400 : 92 : False : 8 : 386063 : root : nginx
image : webp-study-source-firebreathing.png : 1024 : 752 : 92 : False : 8 : 1194091 : root : nginx
| 741 | 517 | 92 | 655406 | 1966217 | 1920 |
For ZopfliPNg - averages 1224 width, 1022 height, 92 quality, 256,931 KB per image (~4.4% smaller than OptiPNG)
image : png24-image1.png : 600 : 400 : 92 : False : 8 : 386195 : root : nginx
image : png24-interlaced-image1.png : 600 : 400 : 92 : False : 8 : 386195 : root : nginx
image : webp-study-source-firebreathing.png : 1024 : 752 : 92 : False : 8 : 1184812 : root : nginx
| 741 | 517 | 92 | 652401 | 1957202 | 1911 |
Disabling JpegOptim, OptiPNG and ZopfliPNG and just rely on ImageMagick convert to resize images.
IMAGICK_RESIZE='y'
IMAGICK_QUALITY='82'
# additional image optimisations after imagemagick
# resizing
JPEGOPTIM='n'
GUETZLI='n'
# choose either OPTIPNG or ZOPFLIPNG
OPTIPNG='n'
ZOPFLIPNG='n'
# max width and height
MAXRES='2048'
# strip meta-data
STRIP='y'
/root/tools/optimise-images/optimise-images.sh profile /home/nginx/domains/domain.com/public/images
------------------------------------------------------------------------------
image profile
image name : width : height : quality : transparency : image depth (bits) : size : user: group
------------------------------------------------------------------------------
images in /home/nginx/domains/domain.com/public/images
logged at /home/optimise-logs/profile-log-270417-163119.log
------------------------------------------------------------------------------
image : dslr_canon_eos_m6_1.jpg : 1200 : 800 : 82 : False : 8 : 159911 : root : nginx
image : png24-image1.png : 600 : 400 : 92 : False : 8 : 386195 : root : nginx
image : png24-interlaced-image1.png : 600 : 400 : 92 : False : 8 : 386195 : root : nginx
image : samsung_s7_mobile_1.jpg : 2048 : 1536 : 82 : False : 8 : 273460 : root : nginx
image : webp-study-source-firebreathing.png : 1024 : 752 : 92 : False : 8 : 1200202 : root : nginx
------------------------------------------------------------------------------
Original or Existing Images:
------------------------------------------------------------------------------
| Avg width | Avg height | Avg quality | Avg size | Total size (Bytes) | Total size (KB) |
| --------- | ---------- | ----------- | -------- | ------------------ | --------------- |
| 1094 | 778 | 88 | 481193 | 2405963 | 2350 |
------------------------------------------------------------------------------
ImageMagick Resource Limits
------------------------------------------------------------------------------
Version: ImageMagick 6.9.8-4 Q16 x86_64 2017-04-25
Resource limits:
Width: 214.7MP
Height: 214.7MP
Area: 67.057GP
Memory: 31.226GiB
Map: 62.4521GiB
Disk: unlimited
File: 196608
Thread: 4
Throttle: 0
Time: unlimited
------------------------------------------------------------------------------
Completion Time: 0.08 seconds
------------------------------------------------------------------------------
Switching from JpegOptim to Google Guetzli compressor just for .jpg image optimisations (not .png)
# additional image optimisations after imagemagick
# resizing
JPEGOPTIM='n'
GUETZLI='y'
# choose either OPTIPNG or ZOPFLIPNG
OPTIPNG='y'
ZOPFLIPNG='n'
Guetzli .jpg optimised profile
/root/tools/optimise-images/optimise-images.sh profile /home/nginx/domains/domain.com/public/images
------------------------------------------------------------------------------
image profile
image name : width : height : quality : transparency : image depth (bits) : size : user: group
------------------------------------------------------------------------------
images in /home/nginx/domains/domain.com/public/images
logged at /home/optimise-logs/profile-log-270417-163538.log
------------------------------------------------------------------------------
image : dslr_canon_eos_m6_1.jpg : 1200 : 800 : 82 : False : 8 : 116224 : root : nginx
image : png24-image1.png : 600 : 400 : 92 : False : 8 : 386063 : root : nginx
image : png24-interlaced-image1.png : 600 : 400 : 92 : False : 8 : 386063 : root : nginx
image : samsung_s7_mobile_1.jpg : 2048 : 1536 : 82 : False : 8 : 273460 : root : nginx
image : webp-study-source-firebreathing.png : 1024 : 752 : 92 : False : 8 : 1194091 : root : nginx
------------------------------------------------------------------------------
Original or Existing Images:
------------------------------------------------------------------------------
| Avg width | Avg height | Avg quality | Avg size | Total size (Bytes) | Total size (KB) |
| --------- | ---------- | ----------- | -------- | ------------------ | --------------- |
| 1094 | 778 | 88 | 471180 | 2355901 | 2301 |
------------------------------------------------------------------------------
ImageMagick Resource Limits
------------------------------------------------------------------------------
Version: ImageMagick 6.9.8-4 Q16 x86_64 2017-04-25
Resource limits:
Width: 214.7MP
Height: 214.7MP
Area: 67.057GP
Memory: 31.226GiB
Map: 62.4521GiB
Disk: unlimited
File: 196608
Thread: 4
Throttle: 0
Time: unlimited
------------------------------------------------------------------------------
Completion Time: 0.08 seconds
------------------------------------------------------------------------------
Image State | Avg Width | Avg Height | Avg Quality | Avg Size (bytes) | Total Size (KB) | Reduction |
---|---|---|---|---|---|---|
Original Images | 1491 | 1075 | 92 | 874538 | 4270 | |
Optimised Default JpegOptim/OptiPNG | 1094 | 778 | 88 | 476711 | 2328 | -45.48% |
Optimised JpegOptim/ZopfliPNG | 1094 | 778 | 88 | 474908 | 2319 | -45.69% |
Optimised Guetzli//OptiPNG | 1094 | 778 | 88 | 471180 | 2301 | -46.11% |
ImageMagick resize only disable JpegOptim/OptiPNG | 1094 | 778 | 88 | 481193 | 2350 | -44.96% |
optimise-images.sh
only operates on the directory max depth = 1 so only images within the directory you point to are profiled and optimised. Subdirectories under the directory you point to are not processed. You can easily script this yourself using a while read loop or for loop.
An example for /home/testsubdir
has 4 subdirectories called subdir1
, subdir2
, subdir3
, subdir4
. For demo purposes each subdirectory has one image bees.png
ls -lah /home/testsubdir/
total 24K
drwxr-xr-x 6 root root 4.0K May 3 16:37 .
drwxr-xr-x. 11 root root 4.0K May 3 16:32 ..
drwxr-xr-x 2 root root 4.0K May 3 16:35 subdir1
drwxr-xr-x 2 root root 4.0K May 3 16:35 subdir2
drwxr-xr-x 2 root root 4.0K May 3 16:35 subdir3
drwxr-xr-x 2 root root 4.0K May 3 16:35 subdri4
recursive listing
ls -lahR /home/testsubdir/
/home/testsubdir/:
total 24K
drwxr-xr-x 6 root root 4.0K May 3 16:37 .
drwxr-xr-x. 11 root root 4.0K May 3 16:32 ..
drwxr-xr-x 2 root root 4.0K May 3 16:35 subdir1
drwxr-xr-x 2 root root 4.0K May 3 16:35 subdir2
drwxr-xr-x 2 root root 4.0K May 3 16:35 subdir3
drwxr-xr-x 2 root root 4.0K May 3 16:35 subdri4
/home/testsubdir/subdir1:
total 180K
drwxr-xr-x 2 root root 4.0K May 3 16:35 .
drwxr-xr-x 6 root root 4.0K May 3 16:37 ..
-rw-r--r-- 1 root root 172K May 3 16:35 bees.png
/home/testsubdir/subdir2:
total 180K
drwxr-xr-x 2 root root 4.0K May 3 16:35 .
drwxr-xr-x 6 root root 4.0K May 3 16:37 ..
-rw-r--r-- 1 root root 172K May 3 16:35 bees.png
/home/testsubdir/subdir3:
total 180K
drwxr-xr-x 2 root root 4.0K May 3 16:35 .
drwxr-xr-x 6 root root 4.0K May 3 16:37 ..
-rw-r--r-- 1 root root 172K May 3 16:35 bees.png
/home/testsubdir/subdri4:
total 180K
drwxr-xr-x 2 root root 4.0K May 3 16:35 .
drwxr-xr-x 6 root root 4.0K May 3 16:37 ..
-rw-r--r-- 1 root root 172K May 3 16:35 bees.png
sample while read that just echo prints subdirectory name using find directory types under /home/testsubdir and pipe subdirectory list to while read loop making directory name a variable = d
find /home/testsubdir/ -mindepth 1 -type d | sort | while read d; do echo "directory: $d"; done
outputs
find /home/testsubdir/ -mindepth 1 -type d | sort | while read d; do echo "directory: $d"; done
directory: /home/testsubdir/subdir1
directory: /home/testsubdir/subdir2
directory: /home/testsubdir/subdir3
directory: /home/testsubdir/subdri4
if you want to include parent directory /home/testsubdir remove the -mindepth 1 from find command
find /home/testsubdir/ type d | sort | while read d; do echo "directory: $d"; done
directory: /home/testsubdir/
directory: /home/testsubdir/subdir2
directory: /home/testsubdir/subdir3
directory: /home/testsubdir/subdir1
directory: /home/testsubdir/subdri4
modify for optimise-images.sh command
to profile
images
find /home/testsubdir/ -type d | sort | while read d; do echo "profile directory: $d"; echo "/root/tools/optimise-images/optimise-images.sh profile $d"; /root/tools/optimise-images/optimise-images.sh profile $d; done
to optimise
images you need to first edit optimise-images.sh as per https://github.com/centminmod/optimise-images and set UNATTENDED_OPTIMISE='y' to disable the backup directory prompt so you can run unattended first. Edit optimise
command for command you want to use.
find /home/testsubdir/ -type d | sort | while read d; do echo "optimise directory: $d"; echo "/root/tools/optimise-images/optimise-images.sh optimise $d"; /root/tools/optimise-images/optimise-images.sh optimise $d; done
or use new optimise-cron
mode specifically made for use as a cronjob as it saves processing time by removing the post-optimisation profile run. Set UNATTENDED_OPTIMISE='y' to disable the backup directory prompt so you can run unattended first. Edit optimise-cron
command for command you want to use.
find /home/testsubdir/ -type d | sort | while read d; do echo "optimise directory: $d"; echo "/root/tools/optimise-images/optimise-images.sh optimise-cron $d"; /root/tools/optimise-images/optimise-images.sh optimise-cron $d; done
or use new optimise-cron-age
mode to filter by image timestamp age + specifically made for use as a cronjob as it saves processing time by removing the post-optimisation profile run. Set UNATTENDED_OPTIMISE='y' to disable the backup directory prompt so you can run unattended first. Edit optimise-cron-age
command for command you want to use.
find /home/testsubdir/ -type d | sort | while read d; do echo "optimise directory: $d"; echo "/root/tools/optimise-images/optimise-images.sh optimise-cron-age $d"; /root/tools/optimise-images/optimise-images.sh optimise-cron-age $d; done
or to optimise-webp
images you need to first edit optimise-images.sh as per https://github.com/centminmod/optimise-images and set UNATTENDED_OPTIMISE='y' to disable the backup directory prompt so you can run unattended first. Edit optimise-webp
command for command you want to use.
find /home/testsubdir/ -type d | sort | while read d; do echo "optimise-webp directory: $d"; echo "/root/tools/optimise-images/optimise-images.sh optimise-webp $d"; /root/tools/optimise-images/optimise-images.sh optimise-webp $d; done
or to optimise-webp-nginx
images you need to first edit optimise-images.sh as per https://github.com/centminmod/optimise-images and set UNATTENDED_OPTIMISE='y' to disable the backup directory prompt so you can run unattended first. Edit optimise-webp-nginx
command for command you want to use.
find /home/testsubdir/ -type d | sort | while read d; do echo "optimise-webp-nginx directory: $d"; echo "/root/tools/optimise-images/optimise-images.sh optimise-webp-nginx $d"; /root/tools/optimise-images/optimise-images.sh optimise-webp-nginx $d; done
This will
- find any subdirectories within
/home/testsubdir
and sort them through a while read loop assigning the subdirectories found to variabled
. - so first directory found
/home/testsubdir/
will be assigned to variabled=/home/testsubdir/
- then echo directory name assigned to variable
d
- then echo the command you will run
- then finally run the actual command on the directory assigned to variable
d
- the while read loop will repeat the previous cycle of steps for next directory found
/home/testsubdir/subdir2
and so forth until all subdirectories found are looped through.
A more recent example of batch image optimisation for Wordpress uploaded images can be found here.