-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't overwrite original if optimized is larger #95
base: main
Are you sure you want to change the base?
Changes from 10 commits
3d2ad00
727bf7f
17832f9
2a00664
c5344ff
53eb99b
99569c9
c5fca2d
e0f3291
60dcb8f
fd171b1
1c95bcc
01cd8b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,7 +56,7 @@ gem 'image_optim_pack' | |
With version: | ||
|
||
```ruby | ||
gem 'image_optim', '~> 0.11' | ||
gem 'image_optim', '~> 0.21' | ||
``` | ||
|
||
If you want to check latest changes: | ||
|
@@ -234,6 +234,9 @@ end | |
image_optim.optimize_images!(Dir['*.*']) | ||
|
||
image_optim.optimize_images_data(datas) | ||
|
||
# Pass options like the sanity check | ||
image_optim.optimize_images!(images, :always_replace => false) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a remainder of previous commits. |
||
``` | ||
|
||
### From rails | ||
|
@@ -271,6 +274,7 @@ optipng: | |
* `:pack` — Require image\_optim\_pack or disable it, by default image\_optim\_pack will be used if available, will turn on `:skip-missing-workers` unless explicitly disabled *(defaults to `nil`)* | ||
* `:skip_missing_workers` — Skip workers with missing or problematic binaries *(defaults to `false`)* | ||
* `:allow_lossy` — Allow lossy workers and optimizations *(defaults to `false`)* | ||
* `:skip_bigger` — Perform sanity check (esp. on jpg) and only return if new image is smaller *(defaults to `false`)* | ||
|
||
Worker can be disabled by passing `false` instead of options hash or by setting option `:disable` to `true`. | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,9 @@ class ImageOptim | |
# Allow lossy workers and optimizations | ||
attr_reader :allow_lossy | ||
|
||
# Skip images where optimization makes them bigger | ||
attr_reader :skip_bigger | ||
|
||
# Initialize workers, specify options using worker underscored name: | ||
# | ||
# pass false to disable worker | ||
|
@@ -67,6 +70,7 @@ def initialize(options = {}) | |
pack | ||
skip_missing_workers | ||
allow_lossy | ||
skip_bigger | ||
].each do |name| | ||
instance_variable_set(:"@#{name}", config.send(name)) | ||
$stderr << "#{name}: #{send(name)}\n" if verbose | ||
|
@@ -101,11 +105,23 @@ def optimize_image(original) | |
end | ||
end | ||
return unless result | ||
return if skip_bigger && result.size > original.size | ||
ImagePath::Optimized.new(result, original) | ||
end | ||
|
||
# Optimize one file in place, return original as OptimizedImagePath or nil if | ||
# optimization failed | ||
# | ||
# Normal operation will obey default logic of workers | ||
# | ||
# image_optim.optimize_image!(original) | ||
# | ||
# Setting always replace to false will perform a sanity check to see if the | ||
# 'optimized' image is indeed smaller than the original. If it is indeed | ||
# larger, the original will not be replaced and the code will act like | ||
# optimization failed | ||
# | ||
# image_optim.optimize_image!(original, :skip_bigger => true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This too |
||
def optimize_image!(original) | ||
original = ImagePath.convert(original) | ||
return unless (result = optimize_image(original)) | ||
|
@@ -140,6 +156,10 @@ def optimize_images(paths, &block) | |
# if block given yields path and result for each image and returns array of | ||
# yield results | ||
# else return array of path and result pairs | ||
# | ||
# Passing optional params will pass them down to the `optimize_image!` call | ||
# | ||
# image_optim.optimize_images!(some_images, :skip_bigger => true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And this |
||
def optimize_images!(paths, &block) | ||
run_method_for(paths, :optimize_image!, &block) | ||
end | ||
|
@@ -163,7 +183,9 @@ def self.method_missing(method, *args, &block) | |
|
||
# Version of image_optim gem spec loaded | ||
def self.version | ||
Gem.loaded_specs['image_optim'].version.to_s rescue 'DEV' | ||
Gem.loaded_specs['image_optim'].version.to_s | ||
rescue | ||
'DEV' | ||
end | ||
|
||
# Full version of image_optim | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -133,6 +133,18 @@ def pack | |
false | ||
end | ||
|
||
# Whether or not to perfom size sanity check | ||
def skip_bigger | ||
opt = get!(:skip_bigger) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be simplified to |
||
|
||
case opt | ||
when true | ||
true | ||
else | ||
false | ||
end | ||
end | ||
|
||
# Skip missing workers, converted to boolean | ||
def skip_missing_workers | ||
if key?(:skip_missing_workers) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,6 +89,41 @@ def temp_copy(image) | |
end | ||
end | ||
end | ||
|
||
describe 'skipping larger' do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To clarify goal and reduce duplication it is better to extract common things using |
||
it 'skips larger files' do | ||
image_optim = ImageOptim.new(:skip_bigger => true) | ||
original = double(:size => 12_345) | ||
optimized = double(:size => 100_000) | ||
|
||
allow(ImageOptim::ImagePath).to receive(:convert).and_return original | ||
|
||
expect(image_optim).to receive(:workers_for_image).with(original). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
and_return true | ||
|
||
allow(ImageOptim::Handler).to receive(:for).and_return optimized | ||
|
||
expect(optimized).to receive(:size).and_return 100_000 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This and next line are redundant |
||
expect(original).to receive(:size).and_return 12_345 | ||
|
||
expect(image_optim.optimize_image(original)).to be nil | ||
end | ||
|
||
it 'does not skips larger files when opt is off' do | ||
image_optim = ImageOptim.new(:skip_bigger => false) | ||
original = double(:size => 12_345) | ||
optimized = double(:original_size => 12_345, :size => 100_000) | ||
|
||
allow(ImageOptim::ImagePath).to receive(:convert).and_return original | ||
|
||
expect(image_optim).to receive(:workers_for_image).with(original). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
and_return true | ||
|
||
allow(ImageOptim::Handler).to receive(:for).and_return optimized | ||
|
||
expect(image_optim.optimize_image(original)).to_not be nil | ||
end | ||
end | ||
end | ||
|
||
it 'ignores text file' do | ||
|
@@ -117,7 +152,7 @@ def temp_copy(image) | |
describe :optimize_image! do | ||
it 'optimizes image and replaces original' do | ||
original = double | ||
optimized = double(:original_size => 12_345) | ||
optimized = double(:original_size => 12_345, :size => 1_000) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is not needed |
||
optimized_wrap = double | ||
image_optim = ImageOptim.new | ||
|
||
|
@@ -215,7 +250,8 @@ def temp_copy(image) | |
image_optim = ImageOptim.new | ||
results = test_images.map do |src| | ||
dst = double | ||
expect(image_optim).to receive(method).with(src).and_return(dst) | ||
expect(image_optim).to receive(method).with(src). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to split the line |
||
and_return(dst) | ||
[src, dst] | ||
end | ||
expect(image_optim.send(list_method, test_images)).to eq(results) | ||
|
@@ -228,7 +264,8 @@ def temp_copy(image) | |
image_optim = ImageOptim.new | ||
results = test_images.map do |src| | ||
dst = double | ||
expect(image_optim).to receive(method).with(src).and_return(dst) | ||
expect(image_optim).to receive(method).with(src). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also no need to split the line |
||
and_return(dst) | ||
[src, dst, :test] | ||
end | ||
expect(image_optim.send(list_method, test_images) do |src, dst| | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue number is missing