image_optim 0.19.1 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.rubocop.yml +3 -0
- data/.travis.yml +9 -2
- data/CHANGELOG.markdown +6 -0
- data/Gemfile +4 -0
- data/README.markdown +4 -2
- data/image_optim.gemspec +2 -2
- data/lib/image_optim.rb +11 -16
- data/lib/image_optim/bin_resolver/bin.rb +2 -1
- data/lib/image_optim/config.rb +3 -3
- data/lib/image_optim/option_definition.rb +14 -0
- data/lib/image_optim/railtie.rb +4 -2
- data/lib/image_optim/runner.rb +3 -2
- data/lib/image_optim/runner/option_parser.rb +4 -0
- data/lib/image_optim/worker.rb +8 -12
- data/lib/image_optim/worker/class_methods.rb +4 -3
- data/lib/image_optim/worker/jpegoptim.rb +10 -2
- data/lib/image_optim/worker/pngcrush.rb +16 -6
- data/lib/image_optim/worker/pngquant.rb +12 -3
- data/script/worker_analysis +14 -3
- data/spec/image_optim/hash_helpers_spec.rb +0 -1
- data/spec/image_optim/worker_spec.rb +31 -0
- data/spec/image_optim_spec.rb +1 -0
- data/spec/images/invisiblepixels/generate +24 -0
- data/spec/images/invisiblepixels/image.png +0 -0
- data/spec/spec_helper.rb +9 -0
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZjNhMTRkY2JmMWRjOTY1NmZiYjI3Yjk3M2U1MTM5YzJkMjMzNWFkMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZjI1MTQ3ZTdkMmNkNjE3ZDdhYzQyZDlmMmYzYzQwMDNjNTUxODY3Yg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZTBiM2M5NmNjY2JhYWExMDNjZDQ3MjlkMmE1MDkxMmNhMGE1OGYwYzkzOTBm
|
10
|
+
ZTcwZTU4ZTFiZDg1ZjBlNjAyNGRlY2MzMzExYzRkNTgzZGNmMjQ1NzcxMzkw
|
11
|
+
YTY0NDJjYTA3NjJjN2Q1ODgwOGEzYzQ3M2I1ZmM3ZmEzNjIwYzA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YzZiYmUzYmJkODI2Yzg5MTUwN2U1ZjI0MzYxMzM1Y2RjMzVmYTEyMzY3Nzcz
|
14
|
+
M2NjODVjMGU2YmM5ZmZlYzM0NmQ5MDA0OTNhYmI2YmJlZDk3MDE4YTU0MWFk
|
15
|
+
YTk0YWJiNmFkNmZmOWU3Yzc5YzRjNzY0MDBkZDM5ODU0NjcyMjM=
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -3,8 +3,9 @@ rvm:
|
|
3
3
|
- 1.8.7
|
4
4
|
- 1.9.2
|
5
5
|
- 1.9.3
|
6
|
-
- 2.0
|
7
|
-
- 2.1
|
6
|
+
- '2.0'
|
7
|
+
- '2.1'
|
8
|
+
- '2.2'
|
8
9
|
- jruby-18mode
|
9
10
|
- jruby-19mode
|
10
11
|
- ree
|
@@ -25,6 +26,12 @@ env:
|
|
25
26
|
- PATH=~/bin:$PATH
|
26
27
|
matrix:
|
27
28
|
fast_finish: true
|
29
|
+
allow_failures:
|
30
|
+
- rvm: '2.2'
|
28
31
|
include:
|
29
32
|
- env: RUBOCOP=true
|
30
33
|
rvm: default
|
34
|
+
addons:
|
35
|
+
code_climate:
|
36
|
+
repo_token:
|
37
|
+
secure: FDikT3JnOJHOAFSaKwVPB1VOphU0sSzAnzQ+YjSt9XFE+9uFQHth/j4rFoVoqALhCj+47trv6spwkbcSjGCVzm+87OI80GkLCCzNjDOz2W4sP9JWItVgS1VoWW+ioPxpLgpguTb3wutwKOUMEAf+40EX657ZiHumM7nNHrF+RCU=
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
## unreleased
|
4
4
|
|
5
|
+
## v0.20.0 (2014-12-15)
|
6
|
+
|
7
|
+
* Ignore and show warning for lossy options `jpegoptim#max_quality` and `pngquant#quality` in default/lossless mode [#71](https://github.com/toy/image_optim/issues/71) [@toy](https://github.com/toy)
|
8
|
+
* Add `:blacken` option to `pngcrush` worker, to blacken fully transparent pixels, on by default [@toy](https://github.com/toy)
|
9
|
+
* Command line option `--no-progress` to disable showing progress of optimizing images [@toy](https://github.com/toy)
|
10
|
+
|
5
11
|
## v0.19.1 (2014-11-22)
|
6
12
|
|
7
13
|
* Blacklist pngcrush 1.7.80 as it loses one color in indexed images [@toy](https://github.com/toy)
|
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
[![Gem Version](https://img.shields.io/gem/v/image_optim.svg?style=flat)](https://rubygems.org/gems/image_optim)
|
2
2
|
[![Build Status](https://img.shields.io/travis/toy/image_optim/master.svg?style=flat)](https://travis-ci.org/toy/image_optim)
|
3
3
|
[![Code Climate](https://img.shields.io/codeclimate/github/toy/image_optim.svg?style=flat)](https://codeclimate.com/github/toy/image_optim)
|
4
|
+
[![Code Climate Coverage](https://img.shields.io/codeclimate/coverage/github/toy/image_optim.svg?style=flat)](https://codeclimate.com/github/toy/image_optim)
|
4
5
|
[![Dependency Status](https://img.shields.io/gemnasium/toy/image_optim.svg?style=flat)](https://gemnasium.com/toy/image_optim)
|
5
6
|
[![Inch CI](http://inch-ci.org/github/toy/image_optim.svg?branch=master&style=flat)](http://inch-ci.org/github/toy/image_optim)
|
6
7
|
|
@@ -289,7 +290,7 @@ Worker has no options
|
|
289
290
|
|
290
291
|
### :jpegoptim =>
|
291
292
|
* `:strip` — List of extra markers to strip: `:comments`, `:exif`, `:iptc`, `:icc` or `:all` *(defaults to `:all`)*
|
292
|
-
* `:max_quality` — Maximum image quality factor `0`..`100
|
293
|
+
* `:max_quality` — Maximum image quality factor `0`..`100`, ignored in default/lossless mode *(defaults to `100`)*
|
293
294
|
|
294
295
|
### :jpegrecompress =>
|
295
296
|
* `:quality` — JPEG quality preset: `0` - low, `1` - medium, `2` - high, `3` - veryhigh *(defaults to `3`)*
|
@@ -307,13 +308,14 @@ Worker has no options
|
|
307
308
|
* `:chunks` — List of chunks to remove or `:alla` - all except tRNS/transparency or `:allb` - all except tRNS and gAMA/gamma *(defaults to `:alla`)*
|
308
309
|
* `:fix` — Fix otherwise fatal conditions such as bad CRCs *(defaults to `false`)*
|
309
310
|
* `:brute` — Brute force try all methods, very time-consuming and generally not worthwhile *(defaults to `false`)*
|
311
|
+
* `:blacken` — Blacken fully transparent pixels *(defaults to `true`)*
|
310
312
|
|
311
313
|
### :pngout =>
|
312
314
|
* `:copy_chunks` — Copy optional chunks *(defaults to `false`)*
|
313
315
|
* `:strategy` — Strategy: `0` - xtreme, `1` - intense, `2` - longest Match, `3` - huffman Only, `4` - uncompressed *(defaults to `0`)*
|
314
316
|
|
315
317
|
### :pngquant =>
|
316
|
-
* `:quality` — min..max - don't save below min, use less colors below max (both in range `0..100`; in yaml - `!ruby/range 0..100`) *(defaults to `100..100`)*
|
318
|
+
* `:quality` — min..max - don't save below min, use less colors below max (both in range `0..100`; in yaml - `!ruby/range 0..100`), ignored in default/lossless mode *(defaults to `100..100`)*
|
317
319
|
* `:speed` — speed/quality trade-off: `1` - slow, `3` - default, `11` - fast & rough *(defaults to `3`)*
|
318
320
|
|
319
321
|
### :svgo =>
|
data/image_optim.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'image_optim'
|
5
|
-
s.version = '0.
|
5
|
+
s.version = '0.20.0'
|
6
6
|
s.summary = %q{Optimize (lossless compress, optionally lossy) images (jpeg, png, gif, svg) using external utilities (advpng, gifsicle, jhead, jpeg-recompress, jpegoptim, jpegrescan, jpegtran, optipng, pngcrush, pngout, pngquant, svgo)}
|
7
7
|
s.homepage = "http://github.com/toy/#{s.name}"
|
8
8
|
s.authors = ['Ivan Kuchin']
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
s.add_development_dependency 'image_optim_pack', '~> 0.2'
|
25
25
|
s.add_development_dependency 'rspec', '~> 3.0'
|
26
26
|
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('1.9.3')
|
27
|
-
s.add_development_dependency 'rubocop', '~> 0.
|
27
|
+
s.add_development_dependency 'rubocop', '~> 0.27'
|
28
28
|
end
|
29
29
|
s.add_development_dependency 'haml', '~> 4.0'
|
30
30
|
end
|
data/lib/image_optim.rb
CHANGED
@@ -58,23 +58,18 @@ class ImageOptim
|
|
58
58
|
# ImageOptim.new(:nice => 20)
|
59
59
|
def initialize(options = {})
|
60
60
|
config = Config.new(options)
|
61
|
-
@nice = config.nice
|
62
|
-
@threads = config.threads
|
63
61
|
@verbose = config.verbose
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
$stderr << "
|
75
|
-
$stderr << "pack: #{pack}\n"
|
76
|
-
$stderr << "skip_missing_workers: #{skip_missing_workers}\n"
|
77
|
-
$stderr << "allow_lossy: #{allow_lossy}\n"
|
62
|
+
$stderr << "config:\n#{config.to_s.gsub(/^/, ' ')}" if verbose
|
63
|
+
|
64
|
+
%w[
|
65
|
+
nice
|
66
|
+
threads
|
67
|
+
pack
|
68
|
+
skip_missing_workers
|
69
|
+
allow_lossy
|
70
|
+
].each do |name|
|
71
|
+
instance_variable_set(:"@#{name}", config.send(name))
|
72
|
+
$stderr << "#{name}: #{send(name)}\n" if verbose
|
78
73
|
end
|
79
74
|
|
80
75
|
@bin_resolver = BinResolver.new(self)
|
@@ -33,8 +33,9 @@ class ImageOptim
|
|
33
33
|
|
34
34
|
WARN_CHECKS = [
|
35
35
|
[:advpng, is < '1.17', 'does not use zopfli'],
|
36
|
-
[:pngquant, is < '2.1', 'may be lossy even with quality `100-`'],
|
37
36
|
[:gifsicle, is < '1.85', 'does not support removing extension blocks'],
|
37
|
+
[:pngcrush, is < '1.7.38', 'does not have blacken flag'],
|
38
|
+
[:pngquant, is < '2.1', 'may be lossy even with quality `100-`'],
|
38
39
|
]
|
39
40
|
|
40
41
|
# Fail if version will not work properly
|
data/lib/image_optim/config.rb
CHANGED
@@ -193,9 +193,9 @@ class ImageOptim
|
|
193
193
|
when /mswin|mingw/
|
194
194
|
require 'win32ole'
|
195
195
|
WIN32OLE.
|
196
|
-
|
197
|
-
|
198
|
-
|
196
|
+
connect('winmgmts://').
|
197
|
+
ExecQuery('select NumberOfLogicalProcessors from Win32_Processor').
|
198
|
+
to_enum.first.NumberOfLogicalProcessors
|
199
199
|
else
|
200
200
|
warn "Unknown architecture (#{host_os}) assuming one processor."
|
201
201
|
1
|
@@ -14,5 +14,19 @@ class ImageOptim
|
|
14
14
|
@description = description.to_s
|
15
15
|
@default, @type, @proc = default, type, proc
|
16
16
|
end
|
17
|
+
|
18
|
+
# Get value for worker from options
|
19
|
+
def value(worker, options)
|
20
|
+
value = options.key?(name) ? options[name] : default
|
21
|
+
if proc
|
22
|
+
if proc.arity == 2
|
23
|
+
worker.instance_exec(value, self, &proc)
|
24
|
+
else
|
25
|
+
worker.instance_exec(value, &proc)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
value
|
29
|
+
end
|
30
|
+
end
|
17
31
|
end
|
18
32
|
end
|
data/lib/image_optim/railtie.rb
CHANGED
@@ -14,13 +14,15 @@ class ImageOptim
|
|
14
14
|
app.assets
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
|
17
|
+
def options
|
18
|
+
if app.config.assets.image_optim == true
|
19
19
|
{}
|
20
20
|
else
|
21
21
|
app.config.assets.image_optim || {}
|
22
22
|
end
|
23
|
+
end
|
23
24
|
|
25
|
+
def register_preprocessor(app)
|
24
26
|
image_optim = ImageOptim.new(options)
|
25
27
|
|
26
28
|
processor = proc do |_context, data|
|
data/lib/image_optim/runner.rb
CHANGED
@@ -46,6 +46,7 @@ class ImageOptim
|
|
46
46
|
def initialize(options)
|
47
47
|
options = HashHelpers.deep_symbolise_keys(options)
|
48
48
|
@recursive = options.delete(:recursive)
|
49
|
+
@progress = options.delete(:show_progress) != false
|
49
50
|
@exclude_dir_globs, @exclude_file_globs = %w[dir file].map do |type|
|
50
51
|
glob = options.delete(:"exclude_#{type}_glob") || '.*'
|
51
52
|
GlobHelpers.expand_braces(glob)
|
@@ -71,8 +72,8 @@ class ImageOptim
|
|
71
72
|
private
|
72
73
|
|
73
74
|
def optimize_images!(to_optimize, &block)
|
74
|
-
@
|
75
|
-
|
75
|
+
to_optimize = to_optimize.with_progress('optimizing') if @progress
|
76
|
+
@image_optim.optimize_images!(to_optimize, &block)
|
76
77
|
end
|
77
78
|
|
78
79
|
def find_to_optimize(paths)
|
@@ -124,6 +124,10 @@ ImageOptim::Runner::OptionParser::DEFINE = proc do |op, options|
|
|
124
124
|
|
125
125
|
op.separator nil
|
126
126
|
|
127
|
+
op.on('--no-progress', 'Disable showing progress') do |show_progress|
|
128
|
+
options[:show_progress] = show_progress
|
129
|
+
end
|
130
|
+
|
127
131
|
op.on('--[no-]threads N', Integer, 'Number of threads or disable '\
|
128
132
|
'(defaults to number of processors)') do |threads|
|
129
133
|
options[:threads] = threads
|
data/lib/image_optim/worker.rb
CHANGED
@@ -27,18 +27,7 @@ class ImageOptim
|
|
27
27
|
end
|
28
28
|
@image_optim = image_optim
|
29
29
|
@allow_lossy = !!options.delete(:allow_lossy)
|
30
|
-
|
31
|
-
value = if options.key?(option_definition.name)
|
32
|
-
options[option_definition.name]
|
33
|
-
else
|
34
|
-
option_definition.default
|
35
|
-
end
|
36
|
-
if option_definition.proc
|
37
|
-
value = option_definition.proc[value]
|
38
|
-
end
|
39
|
-
instance_variable_set("@#{option_definition.name}", value)
|
40
|
-
end
|
41
|
-
|
30
|
+
parse_options(options)
|
42
31
|
assert_no_unknown_options!(options)
|
43
32
|
end
|
44
33
|
|
@@ -100,6 +89,13 @@ class ImageOptim
|
|
100
89
|
|
101
90
|
private
|
102
91
|
|
92
|
+
def parse_options(options)
|
93
|
+
self.class.option_definitions.each do |option_definition|
|
94
|
+
value = option_definition.value(self, options)
|
95
|
+
instance_variable_set("@#{option_definition.name}", value)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
103
99
|
def assert_no_unknown_options!(options)
|
104
100
|
known_keys = self.class.option_definitions.map(&:name)
|
105
101
|
unknown_options = options.reject{ |key, _value| known_keys.include?(key) }
|
@@ -21,7 +21,8 @@ class ImageOptim
|
|
21
21
|
|
22
22
|
# Underscored class name symbol
|
23
23
|
def bin_sym
|
24
|
-
@underscored_name ||=
|
24
|
+
@underscored_name ||=
|
25
|
+
name.
|
25
26
|
split('::').last. # get last part
|
26
27
|
gsub(/([a-z])([A-Z])/, '\1_\2').downcase. # convert AbcDef to abc_def
|
27
28
|
to_sym
|
@@ -33,8 +34,8 @@ class ImageOptim
|
|
33
34
|
|
34
35
|
def option(name, default, type, description = nil, &proc)
|
35
36
|
attr_reader name
|
36
|
-
|
37
|
-
|
37
|
+
OptionDefinition.new(name, default, type, description, &proc).
|
38
|
+
tap{ |option_definition| option_definitions << option_definition }
|
38
39
|
end
|
39
40
|
|
40
41
|
# Create hash with format mapped to list of workers sorted by run order
|
@@ -23,8 +23,16 @@ class ImageOptim
|
|
23
23
|
|
24
24
|
MAX_QUALITY_OPTION =
|
25
25
|
option(:max_quality, 100, 'Maximum image quality factor '\
|
26
|
-
'`0`..`100
|
27
|
-
|
26
|
+
'`0`..`100`, ignored in default/lossless mode') do |v, opt_def|
|
27
|
+
if allow_lossy
|
28
|
+
OptionHelpers.limit_with_range(v.to_i, 0..100)
|
29
|
+
else
|
30
|
+
if v != opt_def.default
|
31
|
+
warn "#{self.class.bin_sym} #{opt_def.name} #{v} ignored " \
|
32
|
+
'in lossless mode'
|
33
|
+
end
|
34
|
+
opt_def.default
|
35
|
+
end
|
28
36
|
end
|
29
37
|
|
30
38
|
# Run first [-1] if max_quality < 100 otherwise with normal priority
|
@@ -19,25 +19,35 @@ class ImageOptim
|
|
19
19
|
option(:brute, false, 'Brute force try all methods, '\
|
20
20
|
'very time-consuming and generally not worthwhile'){ |v| !!v }
|
21
21
|
|
22
|
+
BLACKEN_OPTION =
|
23
|
+
option(:blacken, true, 'Blacken fully transparent pixels'){ |v| !!v }
|
24
|
+
|
22
25
|
# Always run first [-1]
|
23
26
|
def run_order
|
24
27
|
-1
|
25
28
|
end
|
26
29
|
|
27
30
|
def optimize(src, dst)
|
28
|
-
|
31
|
+
flags = %w[
|
29
32
|
-reduce
|
30
33
|
-cc
|
31
34
|
-q
|
35
|
+
]
|
36
|
+
chunks.each do |chunk|
|
37
|
+
flags.push '-rem', chunk
|
38
|
+
end
|
39
|
+
flags.push '-fix' if fix
|
40
|
+
flags.push '-brute' if brute
|
41
|
+
if resolve_bin!(:pngcrush).version >= '1.7.38'
|
42
|
+
flags.push '-blacken' if blacken
|
43
|
+
end
|
44
|
+
|
45
|
+
args = flags + %W[
|
32
46
|
--
|
33
47
|
#{src}
|
34
48
|
#{dst}
|
35
49
|
]
|
36
|
-
|
37
|
-
args.unshift '-rem', chunk
|
38
|
-
end
|
39
|
-
args.unshift '-fix' if fix
|
40
|
-
args.unshift '-brute' if brute
|
50
|
+
|
41
51
|
execute(:pngcrush, *args) && optimized?(src, dst)
|
42
52
|
end
|
43
53
|
end
|
@@ -9,9 +9,18 @@ class ImageOptim
|
|
9
9
|
QUALITY_OPTION =
|
10
10
|
option(:quality, 100..100, NonNegativeIntegerRange, 'min..max - don\'t '\
|
11
11
|
'save below min, use less colors below max (both in range `0..100`; '\
|
12
|
-
'in yaml - `!ruby/range 0..100`)
|
13
|
-
|
14
|
-
|
12
|
+
'in yaml - `!ruby/range 0..100`), ignored in default/lossless '\
|
13
|
+
'mode') do |v, opt_def|
|
14
|
+
if allow_lossy
|
15
|
+
min = OptionHelpers.limit_with_range(v.begin, 0..100)
|
16
|
+
min..OptionHelpers.limit_with_range(v.end, min..100)
|
17
|
+
else
|
18
|
+
if v != opt_def.default
|
19
|
+
warn "#{self.class.bin_sym} #{opt_def.name} #{v} ignored " \
|
20
|
+
'in lossless mode'
|
21
|
+
end
|
22
|
+
opt_def.default
|
23
|
+
end
|
15
24
|
end
|
16
25
|
|
17
26
|
SPEED_OPTION =
|
data/script/worker_analysis
CHANGED
@@ -381,13 +381,24 @@ class Analyser
|
|
381
381
|
@avg_ratio = results.sum(&:ratio) / results.length
|
382
382
|
@avg_difference = results.sum(&:difference) / results.length
|
383
383
|
@max_difference = results.map(&:difference).max
|
384
|
-
@
|
384
|
+
@time = results.sum(&:time)
|
385
|
+
|
386
|
+
@warn_level = calculate_warn_level
|
387
|
+
@speed = calculate_speed
|
388
|
+
end
|
389
|
+
|
390
|
+
private
|
391
|
+
|
392
|
+
def calculate_warn_level
|
393
|
+
case
|
385
394
|
when max_difference >= 0.1 then 'high'
|
386
395
|
when max_difference >= 0.01 then 'medium'
|
387
396
|
when max_difference >= 0.001 then 'low'
|
388
397
|
end
|
389
|
-
|
390
|
-
|
398
|
+
end
|
399
|
+
|
400
|
+
def calculate_speed
|
401
|
+
case
|
391
402
|
when time > 0 then (original_size - optimized_size) / time
|
392
403
|
when original_size == optimized_size then 0
|
393
404
|
else 1.0 / 0.0
|
@@ -156,4 +156,35 @@ describe ImageOptim::Worker do
|
|
156
156
|
end
|
157
157
|
end
|
158
158
|
end
|
159
|
+
|
160
|
+
describe :option do
|
161
|
+
it 'runs option block in context of worker' do
|
162
|
+
# don't add Abc to list of wokers
|
163
|
+
allow(ImageOptim::Worker).to receive(:inherited)
|
164
|
+
|
165
|
+
stub_const('Abc', Class.new(Worker) do
|
166
|
+
option(:test, 1, 'Test context') do |_v|
|
167
|
+
some_instance_method
|
168
|
+
end
|
169
|
+
end)
|
170
|
+
|
171
|
+
expect_any_instance_of(Abc).
|
172
|
+
to receive(:some_instance_method).and_return(20)
|
173
|
+
expect(Abc.new(ImageOptim.new).test).to eq(20)
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'returns instance of OptionDefinition' do
|
177
|
+
# don't add Abc to list of wokers
|
178
|
+
allow(ImageOptim::Worker).to receive(:inherited)
|
179
|
+
|
180
|
+
definition = nil
|
181
|
+
Class.new(Worker) do
|
182
|
+
definition = option(:test, 1, 'Test'){ |v| v }
|
183
|
+
end
|
184
|
+
|
185
|
+
expect(definition).to be_an(ImageOptim::OptionDefinition)
|
186
|
+
expect(definition.name).to eq(:test)
|
187
|
+
expect(definition.default).to eq(1)
|
188
|
+
end
|
189
|
+
end
|
159
190
|
end
|
data/spec/image_optim_spec.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
Dir.chdir(File.dirname(__FILE__))
|
4
|
+
|
5
|
+
require 'shellwords'
|
6
|
+
|
7
|
+
side = 64
|
8
|
+
|
9
|
+
IO.popen(%W[
|
10
|
+
convert
|
11
|
+
-depth 8
|
12
|
+
-size #{side}x#{side}
|
13
|
+
-strip
|
14
|
+
rgba:-
|
15
|
+
PNG32:image.png
|
16
|
+
].shelljoin, 'w') do |f|
|
17
|
+
side.times do |a|
|
18
|
+
side.times do |b|
|
19
|
+
alpha = [0, 1, 0x7f, 0xff][(a / 8 + b / 8) % 4]
|
20
|
+
f << [rand(256), rand(256), rand(256), alpha].pack('C*')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
system 'image_optim --pngcrush-blacken=n image.png'
|
Binary file
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
if ENV['CODECLIMATE_REPO_TOKEN']
|
2
|
+
begin
|
3
|
+
require 'codeclimate-test-reporter'
|
4
|
+
CodeClimate::TestReporter.start
|
5
|
+
rescue LoadError => e
|
6
|
+
$stderr.puts "Got following while loading codeclimate-test-reporter: #{e}"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
1
10
|
RSpec.configure do |c|
|
2
11
|
c.alias_example_to :they
|
3
12
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_optim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Kuchin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fspath
|
@@ -126,14 +126,14 @@ dependencies:
|
|
126
126
|
requirements:
|
127
127
|
- - ~>
|
128
128
|
- !ruby/object:Gem::Version
|
129
|
-
version: 0.
|
129
|
+
version: '0.27'
|
130
130
|
type: :development
|
131
131
|
prerelease: false
|
132
132
|
version_requirements: !ruby/object:Gem::Requirement
|
133
133
|
requirements:
|
134
134
|
- - ~>
|
135
135
|
- !ruby/object:Gem::Version
|
136
|
-
version: 0.
|
136
|
+
version: '0.27'
|
137
137
|
- !ruby/object:Gem::Dependency
|
138
138
|
name: haml
|
139
139
|
requirement: !ruby/object:Gem::Requirement
|
@@ -220,6 +220,8 @@ files:
|
|
220
220
|
- spec/images/decompressed.jpeg
|
221
221
|
- spec/images/icecream.gif
|
222
222
|
- spec/images/image.jpg
|
223
|
+
- spec/images/invisiblepixels/generate
|
224
|
+
- spec/images/invisiblepixels/image.png
|
223
225
|
- spec/images/lena.jpg
|
224
226
|
- spec/images/orient/0.jpg
|
225
227
|
- spec/images/orient/1.jpg
|
@@ -260,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
260
262
|
version: '0'
|
261
263
|
requirements: []
|
262
264
|
rubyforge_project: image_optim
|
263
|
-
rubygems_version: 2.4.
|
265
|
+
rubygems_version: 2.4.5
|
264
266
|
signing_key:
|
265
267
|
specification_version: 4
|
266
268
|
summary: Optimize (lossless compress, optionally lossy) images (jpeg, png, gif, svg)
|
@@ -284,6 +286,8 @@ test_files:
|
|
284
286
|
- spec/images/decompressed.jpeg
|
285
287
|
- spec/images/icecream.gif
|
286
288
|
- spec/images/image.jpg
|
289
|
+
- spec/images/invisiblepixels/generate
|
290
|
+
- spec/images/invisiblepixels/image.png
|
287
291
|
- spec/images/lena.jpg
|
288
292
|
- spec/images/orient/0.jpg
|
289
293
|
- spec/images/orient/1.jpg
|
@@ -303,3 +307,4 @@ test_files:
|
|
303
307
|
- spec/images/transparency2.png
|
304
308
|
- spec/images/vergroessert.jpg
|
305
309
|
- spec/spec_helper.rb
|
310
|
+
has_rdoc:
|