From 02d2bee7dda86b3d5006c8e130b34fe6c4267f4b Mon Sep 17 00:00:00 2001 From: Will Jordan Date: Sun, 5 Oct 2014 10:43:05 -0700 Subject: [PATCH] Add support for jpeg-recompress from danielgtaylor/jpeg-archive --- .travis.yml | 6 ++++ README.markdown | 8 +++++ lib/image_optim.rb | 2 +- lib/image_optim/bin_resolver/bin.rb | 2 +- lib/image_optim/worker/jpegrecompress.rb | 38 ++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 lib/image_optim/worker/jpegrecompress.rb diff --git a/.travis.yml b/.travis.yml index fb424dbc..c1e84db6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,6 +37,12 @@ before_install: - wget http://static.jonof.id.au/dl/kenutils/pngout-$PNGOUT_VERSION-linux.tar.gz - tar -xzf pngout-$PNGOUT_VERSION-linux.tar.gz - mv pngout-$PNGOUT_VERSION-linux/x86_64/pngout ~/bin + + - echo 'Installing jpeg-recompress:' + - JPEGARCHIVE_VERSION=2.0.1 + - wget https://github.com/danielgtaylor/jpeg-archive/releases/download/$JPEGARCHIVE_VERSION/jpeg-archive-$JPEGARCHIVE_VERSION-linux.tar.bz2 + - tar -xjf jpeg-archive-$JPEGARCHIVE_VERSION-linux.tar.bz2 jpeg-recompress + - mv jpeg-recompress ~/bin env: - PATH=~/bin:$PATH matrix: diff --git a/README.markdown b/README.markdown index d0cacca2..7018c06c 100644 --- a/README.markdown +++ b/README.markdown @@ -153,6 +153,11 @@ _Note: pngout is free to use even in commercial soft, but you can not redistribu npm install -g svgo ``` +### jpeg-recompress installation (optional) + +Download and install the `jpeg-recompress` binary from the [JPEG-Archive Releases](https://github.com/danielgtaylor/jpeg-archive/releases) page, +or follow the instructions to [build from source](https://github.com/danielgtaylor/jpeg-archive#building). + ## Usage ### From shell @@ -260,6 +265,9 @@ Worker has no options * `:strip` — List of extra markers to strip: `:comments`, `:exif`, `:iptc`, `:icc` or `:all` *(defaults to `:all`)* * `:max_quality` — Maximum image quality factor `0`..`100` *(defaults to `100`)* +### :jpegrecompress => +* `:quality` - JPEG quality preset: `0` - low, `1` - medium, `2` - high, `3` - veryhigh, `4` - lossless *(defaults to `4`)* + ### :jpegtran => * `:copy_chunks` — Copy all chunks *(defaults to `false`)* * `:progressive` — Create progressive JPEG file *(defaults to `true`)* diff --git a/lib/image_optim.rb b/lib/image_optim.rb index 17b521ea..47336b31 100644 --- a/lib/image_optim.rb +++ b/lib/image_optim.rb @@ -221,7 +221,7 @@ def apply_threading(enum) %w[ pngcrush pngout advpng optipng pngquant - jhead jpegoptim jpegtran + jhead jpegoptim jpegrecompress jpegtran gifsicle svgo ].each do |worker| diff --git a/lib/image_optim/bin_resolver/bin.rb b/lib/image_optim/bin_resolver/bin.rb index 205a959e..dc866cef 100644 --- a/lib/image_optim/bin_resolver/bin.rb +++ b/lib/image_optim/bin_resolver/bin.rb @@ -62,7 +62,7 @@ def version_string `#{path.shellescape} --version 2> /dev/null`[/\d+(\.\d+){1,}/] when :svgo `#{path.shellescape} --version 2>&1`[/\d+(\.\d+){1,}/] - when :jhead + when :jhead, :'jpeg-recompress' `#{path.shellescape} -V 2> /dev/null`[/\d+(\.\d+){1,}/] when :jpegtran `#{path.shellescape} -v - 2>&1`[/version (\d+\S*)/, 1] diff --git a/lib/image_optim/worker/jpegrecompress.rb b/lib/image_optim/worker/jpegrecompress.rb new file mode 100644 index 00000000..dd7edfbf --- /dev/null +++ b/lib/image_optim/worker/jpegrecompress.rb @@ -0,0 +1,38 @@ +require 'image_optim/worker' +require 'image_optim/option_helpers' + +class ImageOptim + class Worker + # http://www.kokkonen.net/tjko/projects.html + class Jpegrecompress < Worker + QUALITY_OPTION = + option(:quality, 4, 'JPEG quality preset: '\ + '`0` - low, '\ + '`1` - medium, '\ + '`2` - high, '\ + '`3` - veryhigh, '\ + '`4` - lossless') do |v| + OptionHelpers.limit_with_range(v.to_i, 0..4) + end + + QUALITY_OPTIONS = %i(low medium high veryhigh lossless) + + def used_bins + QUALITY_OPTIONS[quality] == :lossless ? [] : [:'jpeg-recompress'] + end + + # Run first [-1] if max_quality < 100 otherwise with normal priority + def run_order + -1 + end + + def optimize(src, dst) + quality_str = QUALITY_OPTIONS[quality] + return false if quality_str == :lossless + src.copy(dst) + args = ['-q', quality_str, dst, dst] + execute(:'jpeg-recompress', *args) && optimized?(src, dst) + end + end + end +end