* Add resize_to_cover
* Add an initial resize_to_cover test
* Fix method name and add passing tests for VIPS
* Add cover method for MiniMagick and add tests
* Rearrange VIPS tests to match source code order
* Update CHANGELOG.md
* Add documentation for cover to both engines
The following test currently fails on CI:
1) Failure:
ImageProcessing::Vips::#resize_and_pad#test_0006_accepts thumbnail
options [/home/runner/work/image_processing/image_processing/test/vips_test.rb:310]:
Expected 1 to be > 3.
By using `:entropy` instead of `:centre` the images differ more
according to DHash.
The `MiniTest` was renamed to `Minitest`:
https://github.com/minitest/minitest/commit/9a57c520ceac76abfe6105866f8548a94eb357b6
And the `MiniTest` constant is now loaded just when `MT_COMPAT` environment variable is set:
https://github.com/minitest/minitest/commit/a2c6c18570f6f0a1bf6af70fe3b6d9599a13fdd6
This fixes following issue:
~~~
$ ruby -Ilib:test -e 'Dir.glob "./test/**/*_test.rb", &method(:require)'
/builddir/build/BUILD/test/test_helper.rb:17:in `<top (required)>': uninitialized constant MiniTest (NameError)
class MiniTest::Test
^^^^^^^^
Did you mean? Minitest
from <internal:/usr/share/rubygems/rubygems/core_ext/kernel_require.rb>:85:in `require'
from <internal:/usr/share/rubygems/rubygems/core_ext/kernel_require.rb>:85:in `require'
from /builddir/build/BUILD/image_processing-1.12.2/usr/share/gems/gems/image_processing-1.12.2/test/builder_test.rb:1:in `<top (required)>'
from <internal:/usr/share/rubygems/rubygems/core_ext/kernel_require.rb>:85:in `require'
from <internal:/usr/share/rubygems/rubygems/core_ext/kernel_require.rb>:85:in `require'
from <internal:dir>:220:in `glob'
from -e:1:in `<main>'
~~~
If the operations are coming from user input, this could allow the user
to execute arbitrary shell commands via `Kernel#system` and
`Kernel#spawn`:
ImageProcessing::Vips.apply({ system: "echo something" })
We prevent this by using `#public_send` instead of `#send`, which goes
to method missing instead of calling private methods, which include
`Kernel#system` and `Kernel#spawn`.
Phashion currently doesn't install on Apple Silicon, and it doesn't seem
it's going to get fixed.
An upside is that this will now work on JRuby as well, since dhash-vips
doesn't use C extensions.
File.extname was updated in ruby 2.7 to return “.” when the file ends in a dot. Previously it was returning an empty string. This can break determining the destination format.
When performing resizing with loader options, the following gets called
internally:
Vips::Image.new_from_file("/path/to/source.jpg")
.autorot
.thumbnail_image(400, 400)
.write_to_file("/path/to/destination.jpg")
Prior to libvips 8.9.0, this code would produce a correctly auto-rotated
image. However, in libvips 8.9.0, the auto-rotation from `autorot` and
the default auto-rotation performed by `thumbnail_image` cancel each
other out, leaving the image rotated.
We fix this by disabling auto-rotation for the `thumbnail` operation, so
that the only auto-rotation done is by `autorot`. In the resize-on-load
case we leave `thumbnail` to auto-rotate, as in that case `autorot` is
not called beforehand.
Closes#64
Ruby 2.7 introduced warnings around implicit conversions between
kwargs and hashes, so we fix the warnings.
If we have the following method:
def foo(a, b, **c)
end
And we pass arguments like this:
args = [1, 2, { x: :y }]
foo(*args)
This will trigger a kwarg warning on Ruby 2.7. So, we need to explicitly
pass the last argument as kwargs if it is a hash.
Surprisingly, the warning was only triggered when using #apply:
# would trigger the kwargs warning
ImageProcessing::Vips
.source("/path/to/image")
.apply!(resize_to_limit: [400, 400, sharpen: false])
And not when calling operation directly:
# wouldn't trigger the kwargs warning
ImageProcessing::Vips
.source("/path/to/image")
.resize_to_limit!(400, 400, sharpen: false)
Even though final options are exactly the same, so the code that's then
executed on processing should be the same.
options1 = ImageProcessing::Vips
.apply(resize_to_limit: [400, 400, sharpen: false])
options2 = ImageProcessing::Vips
.resize_to_limit(400, 400, sharpen: false)
options1 == options2 #=> true
The warning was coming from Processor.apply_operation when we would call
an underlying macro. It's probably a bug in Ruby, both examples should have
triggered the same warning. But I couldn't isolate it, so instead we
add an additional test case for #apply.
Co-authored-by: Janko Marohnić <janko.marohnic@gmail.com>
By default, ImageMagick guesses the input file type based on magic
headers and other information. However, it's not always possible for
ImageMagick to correctly identify the file based on its content, and in
some cases it can be a security flaw. So, ImageMagick gives you the
ability to explicitly set the input file type.
convert jpg:input.jpg ...
The vips backend already provides the equivalent :loader option, so we
use the same name for the minimagick counterpart as well.
ImageProcessing::MiniMagick
.source("input.jpg")
.loader(loader: "jpg")
# ...
Work in #22 added automatic image sharpening for Vips. However, discovered in #55 `conv()` defaults to float precision and can leave to visual artifacts in some scenarios. Per @jcupitt recommendation, we can add `precision: :integer` to conv and this should also give us a speed-up, since int convolutions will use SIMD. https://github.com/janko/image_processing/issues/55Fixes#55
Sometimes libvips is not able to identify the source image type, even if
there is a corresponding loader. In this case it's useful to be able to
tell libvips which loader to use. So, we add a `:loader` option that
does just that:
ImageProcessing::Vips
.loader(loader: :svg) # calls `Vips::Image.svgload`
# ...
For symmetry, we also add a `:saver` option, just in case libvips isn't
able to correctly identify the file extension of the destination path.
ImageProcessing::Vips
.saver(saver: :tiff) # calls `Vips::Image#tiffsave`
# ...
Closes#49