Skip to content

Commit

Permalink
Support resize-on-load for resize to cover
Browse files Browse the repository at this point in the history
We can now rename it back to `#resize_to_cover`, since vips backend
requires all `resize_to_*` operations to support resize-on-load.
  • Loading branch information
janko committed Jun 15, 2024
1 parent c2a9a73 commit 9d72e46
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 38 deletions.
6 changes: 3 additions & 3 deletions doc/minimagick.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ the [MiniMagick] gem (which is installed with the image_processing gem).
* [`#resize_to_fit`](#resize_to_fit)
* [`#resize_to_fill`](#resize_to_fill)
* [`#resize_and_pad`](#resize_and_pad)
* [`#cover`](#cover)
* [`#resize_to_cover`](#resize_to_cover)
* [`#crop`](#crop)
* [`#rotate`](#rotate)
* [`#composite`](#composite)
Expand Down Expand Up @@ -190,15 +190,15 @@ It accepts `:gravity` for specifying the [gravity] to apply while cropping
pipeline.resize_and_pad!(400, 400, gravity: "north-west")
```

#### `#cover`
#### `#resize_to_cover`

Resizes the image to cover the specified dimensions while retaining the
original aspect ratio. The overflowing areas will not be cropped.

```rb
pipeline = ImageProcessing::MiniMagick.source(image) # 600x800

result = pipeline.cover!(300, 300)
result = pipeline.resize_to_cover!(300, 300)

MiniMagick::Image.new(result.path).dimensions #=> [300, 400]
```
Expand Down
8 changes: 4 additions & 4 deletions doc/vips.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The `ImageProcessing::Vips` module contains processing macros that use the
* [`#resize_to_fit`](#resize_to_fit)
* [`#resize_to_fill`](#resize_to_fill)
* [`#resize_and_pad`](#resize_and_pad)
* [`#cover`](#cover)
* [`#resize_to_cover`](#resize_to_cover)
* [`#crop`](#crop)
* [`#rotate`](#rotate)
* [`#composite`](#composite)
Expand Down Expand Up @@ -221,23 +221,23 @@ pipeline.resize_to_fill!(400, 400, linear: true)

See [`vips_thumbnail()`] and [`vips_gravity()`] for more details.

#### `#cover`
#### `#resize_to_cover`

Resizes the image to cover the specified dimensions while retaining the
original aspect ratio. The overflowing areas will not be cropped.

```rb
pipeline = ImageProcessing::Vips.source(image) # 600x800

result = pipeline.cover!(300, 300)
result = pipeline.resize_to_cover!(300, 300)

Vips::Image.new_from_file(result.path).size #=> [300, 400]
```

Any additional options (except `crop`) are forwarded to [`Vips::Image#thumbnail_image`]:

```rb
pipeline.cover!(400, 400, linear: true)
pipeline.resize_to_cover!(400, 400, linear: true)
```

See [`vips_thumbnail()`] for more details.
Expand Down
2 changes: 1 addition & 1 deletion lib/image_processing/mini_magick.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def resize_and_pad(width, height, background: :transparent, gravity: "Center", *

# Resizes the image to cover the specified dimensions, without
# cropping the excess.
def cover(width, height, **options)
def resize_to_cover(width, height, **options)
thumbnail("#{width}x#{height}^", **options)
end

Expand Down
4 changes: 3 additions & 1 deletion lib/image_processing/vips.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ def resize_and_pad(width, height, gravity: "centre", extend: nil, background: ni

# Resizes the image to cover the specified dimensions, without
# cropping the excess.
def cover(width, height, **options)
def resize_to_cover(width, height, **options)
image = self.image.is_a?(String) ? ::Vips::Image.new_from_file(self.image) : self.image

image_ratio = Rational(image.width, image.height)
thumbnail_ratio = Rational(width, height)

Expand Down
26 changes: 13 additions & 13 deletions test/mini_magick_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -367,57 +367,57 @@
end
end

describe "#cover" do
describe "#resize_to_cover" do
before do
@portrait_pipeline = ImageProcessing::MiniMagick.source(@portrait)
@landscape_pipeline = ImageProcessing::MiniMagick.source(@landscape)
@square_pipeline = ImageProcessing::MiniMagick.source(@square)
end

it "resizes the portrait image to fill out the given landscape dimensions" do
assert_dimensions [300, 400], @portrait_pipeline.cover!(300, 200)
assert_dimensions [300, 400], @portrait_pipeline.resize_to_cover!(300, 200)
end

it "resizes the portrait image to fill out the given portrait dimensions" do
assert_dimensions [225, 300], @portrait_pipeline.cover!(200, 300)
assert_dimensions [225, 300], @portrait_pipeline.resize_to_cover!(200, 300)
end

it "resizes the portrait image to fill out the given square dimensions" do
assert_dimensions [300, 400], @portrait_pipeline.cover!(300, 300)
assert_dimensions [300, 400], @portrait_pipeline.resize_to_cover!(300, 300)
end

it "resizes the landscape image to fill out the given portrait dimensions" do
assert_dimensions [400, 300], @landscape_pipeline.cover!(200, 300)
assert_dimensions [400, 300], @landscape_pipeline.resize_to_cover!(200, 300)
end

it "resizes the landscape image to fill out the given landscape dimensions" do
assert_dimensions [300, 225], @landscape_pipeline.cover!(300, 200)
assert_dimensions [300, 225], @landscape_pipeline.resize_to_cover!(300, 200)
end

it "resizes the landscape image to fill out the given square dimensions" do
assert_dimensions [400, 300], @landscape_pipeline.cover!(300, 300)
assert_dimensions [400, 300], @landscape_pipeline.resize_to_cover!(300, 300)
end

it "resizes the square image to fill out the given portrait dimensions" do
assert_dimensions [300, 300], @square_pipeline.cover!(200, 300)
assert_dimensions [300, 300], @square_pipeline.resize_to_cover!(200, 300)
end

it "resizes the square image to fill out the given landscape dimensions" do
assert_dimensions [300, 300], @square_pipeline.cover!(300, 200)
assert_dimensions [300, 300], @square_pipeline.resize_to_cover!(300, 200)
end

it "resizes the square image to fill out the given square dimensions" do
assert_dimensions [300, 300], @square_pipeline.cover!(300, 300)
assert_dimensions [300, 300], @square_pipeline.resize_to_cover!(300, 300)
end

it "produces correct image" do
expected = fixture_image("cover.jpg")
assert_similar expected, @portrait_pipeline.cover!(300, 200)
assert_similar expected, @portrait_pipeline.resize_to_cover!(300, 200)
end

it "accepts sharpening options" do
sharpened = @portrait_pipeline.cover!(400, 400, sharpen: { sigma: 1 })
normal = @portrait_pipeline.cover!(400, 400, sharpen: false)
sharpened = @portrait_pipeline.resize_to_cover!(400, 400, sharpen: { sigma: 1 })
normal = @portrait_pipeline.resize_to_cover!(400, 400, sharpen: false)
assert sharpened.size > normal.size, "Expected sharpened thumbnail to have bigger filesize than not sharpened thumbnail"
end
end
Expand Down
32 changes: 16 additions & 16 deletions test/vips_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -323,68 +323,68 @@
end
end

describe "#cover" do
describe "#resize_to_cover" do
before do
@portrait_pipeline = ImageProcessing::Vips.source(@portrait)
@landscape_pipeline = ImageProcessing::Vips.source(@landscape)
@square_pipeline = ImageProcessing::Vips.source(@square)
end

it "resizes the portrait image to fill out the given landscape dimensions" do
assert_dimensions [300, 400], @portrait_pipeline.cover!(300, 200)
assert_dimensions [300, 400], @portrait_pipeline.resize_to_cover!(300, 200)
end

it "resizes the portrait image to fill out the given portrait dimensions" do
assert_dimensions [225, 300], @portrait_pipeline.cover!(200, 300)
assert_dimensions [225, 300], @portrait_pipeline.resize_to_cover!(200, 300)
end

it "resizes the portrait image to fill out the given square dimensions" do
assert_dimensions [300, 400], @portrait_pipeline.cover!(300, 300)
assert_dimensions [300, 400], @portrait_pipeline.resize_to_cover!(300, 300)
end

it "resizes the landscape image to fill out the given portrait dimensions" do
assert_dimensions [400, 300], @landscape_pipeline.cover!(200, 300)
assert_dimensions [400, 300], @landscape_pipeline.resize_to_cover!(200, 300)
end

it "resizes the landscape image to fill out the given landscape dimensions" do
assert_dimensions [300, 225], @landscape_pipeline.cover!(300, 200)
assert_dimensions [300, 225], @landscape_pipeline.resize_to_cover!(300, 200)
end

it "resizes the landscape image to fill out the given square dimensions" do
assert_dimensions [400, 300], @landscape_pipeline.cover!(300, 300)
assert_dimensions [400, 300], @landscape_pipeline.resize_to_cover!(300, 300)
end

it "resizes the square image to fill out the given portrait dimensions" do
assert_dimensions [300, 300], @square_pipeline.cover!(200, 300)
assert_dimensions [300, 300], @square_pipeline.resize_to_cover!(200, 300)
end

it "resizes the square image to fill out the given landscape dimensions" do
assert_dimensions [300, 300], @square_pipeline.cover!(300, 200)
assert_dimensions [300, 300], @square_pipeline.resize_to_cover!(300, 200)
end

it "resizes the square image to fill out the given square dimensions" do
assert_dimensions [300, 300], @square_pipeline.cover!(300, 300)
assert_dimensions [300, 300], @square_pipeline.resize_to_cover!(300, 300)
end

it "produces correct image" do
expected = fixture_image("cover.jpg")
assert_similar expected, @portrait_pipeline.cover!(300, 200)
assert_similar expected, @portrait_pipeline.resize_to_cover!(300, 200)
end

it "accepts thumbnail options except :crop" do
attention = @portrait_pipeline.cover!(400, 400, crop: :attention)
centre = @portrait_pipeline.cover!(400, 400, crop: :centre)
attention = @portrait_pipeline.resize_to_cover!(400, 400, crop: :attention)
centre = @portrait_pipeline.resize_to_cover!(400, 400, crop: :centre)
assert_similar centre, attention
end

it "accepts sharpening options" do
sharpened = @portrait_pipeline.cover!(400, 400, sharpen: ImageProcessing::Vips::Processor::SHARPEN_MASK)
normal = @portrait_pipeline.cover!(400, 400, sharpen: false)
sharpened = @portrait_pipeline.resize_to_cover!(400, 400, sharpen: ImageProcessing::Vips::Processor::SHARPEN_MASK)
normal = @portrait_pipeline.resize_to_cover!(400, 400, sharpen: false)
assert sharpened.size > normal.size, "Expected sharpened thumbnail to have bigger filesize than not sharpened thumbnail"
end

it "sharpening uses integer precision" do
sharpened = @portrait_pipeline.cover(400, 400).call(save: false)
sharpened = @portrait_pipeline.resize_to_cover(400, 400).call(save: false)
assert_equal :uchar, sharpened.format
end
end
Expand Down

0 comments on commit 9d72e46

Please sign in to comment.