Skip to content

Commit

Permalink
Add crop_resize Dragonfly processor
Browse files Browse the repository at this point in the history
The build in thumb processor does not support to resize the image after
it has been cropped.

In order to make it work in dragonfly 1.4 we add our own processor.
  • Loading branch information
tvdeyen committed May 25, 2021
1 parent ba5b636 commit acf28b1
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 5 deletions.
2 changes: 1 addition & 1 deletion alchemy_cms.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Gem::Specification.new do |gem|
gem.add_runtime_dependency "awesome_nested_set", ["~> 3.1"]
gem.add_runtime_dependency "cancancan", [">= 2.1", "< 4.0"]
gem.add_runtime_dependency "coffee-rails", [">= 4.0", "< 6.0"]
gem.add_runtime_dependency "dragonfly", ["~> 1.0", ">= 1.0.7"]
gem.add_runtime_dependency "dragonfly", ["~> 1.4"]
gem.add_runtime_dependency "dragonfly_svg", ["~> 0.0.4"]
gem.add_runtime_dependency "gutentag", ["~> 2.2", ">= 2.2.1"]
gem.add_runtime_dependency "handlebars_assets", ["~> 0.23"]
Expand Down
6 changes: 3 additions & 3 deletions app/models/alchemy/picture/transformations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,12 @@ def center_crop(dimensions, upsample)
# Use imagemagick to custom crop an image. Uses -thumbnail for better performance when resizing.
#
def xy_crop_resize(dimensions, top_left, crop_dimensions, upsample)
crop_argument = "-crop #{dimensions_to_string(crop_dimensions)}"
crop_argument = dimensions_to_string(crop_dimensions)
crop_argument += "+#{top_left[:x]}+#{top_left[:y]}"

resize_argument = "-resize #{dimensions_to_string(dimensions)}"
resize_argument = dimensions_to_string(dimensions)
resize_argument += ">" unless upsample
image_file.convert "#{crop_argument} #{resize_argument}"
image_file.crop_resize(crop_argument, resize_argument)
end

# Used when centercropping.
Expand Down
5 changes: 5 additions & 0 deletions config/initializers/dragonfly.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true
require "dragonfly_svg"
require "alchemy/dragonfly/processors/crop_resize"

# Logger
Dragonfly.logger = Rails.logger
Expand All @@ -12,3 +13,7 @@

# Dragonfly 1.4.0 only allows `quality` as argument to `encode`
Dragonfly::ImageMagick::Processors::Encode::WHITELISTED_ARGS << "flatten"

Rails.application.config.after_initialize do
Dragonfly.app(:alchemy_pictures).add_processor(:crop_resize, Alchemy::Dragonfly::Processors::CropResize.new)
end
35 changes: 35 additions & 0 deletions lib/alchemy/dragonfly/processors/crop_resize.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

require "dragonfly/image_magick/commands"

module Alchemy
module Dragonfly
module Processors
class CropResize
include ::Dragonfly::ParamValidators

IS_CROP_ARGUMENT = ->(args_string) {
args_string.match?(::Dragonfly::ImageMagick::Processors::Thumb::CROP_GEOMETRY)
}

IS_RESIZE_ARGUMENT = ->(args_string) {
args_string.match?(::Dragonfly::ImageMagick::Processors::Thumb::RESIZE_GEOMETRY)
}

def call(content, crop_argument, resize_argument)
validate!(crop_argument, &IS_CROP_ARGUMENT)
validate!(resize_argument, &IS_RESIZE_ARGUMENT)
::Dragonfly::ImageMagick::Commands.convert(
content,
"-crop #{crop_argument} -resize #{resize_argument}"
)
end

def update_url(attrs, _args = "", opts = {})
format = opts["format"]
attrs.ext = format if format
end
end
end
end
end
23 changes: 23 additions & 0 deletions spec/libraries/dragonfly/processors/crop_resize_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

require "rails_helper"
require_relative "../../../support/dragonfly_test_app"

RSpec.describe Alchemy::Dragonfly::Processors::CropResize do
let(:app) { dragonfly_test_app }
let(:file) { Pathname.new(File.expand_path("../../../fixtures/80x60.png", __dir__)) }
let(:image) { Dragonfly::Content.new(app, file) }
let(:processor) { described_class.new }

it "validates bad crop and resize arguments" do
expect {
processor.call(image, "h4ck", "m3")
}.to raise_error(Dragonfly::ParamValidators::InvalidParameter)
end

it "works with correct crop and resize arguments" do
expect {
processor.call(image, "4x4+0+0", "20x20>")
}.to_not raise_error
end
end
2 changes: 1 addition & 1 deletion spec/models/alchemy/picture_variant_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
end

it "crops and resizes the picture" do
expect(subject.steps[0].arguments).to eq(["-crop 123x44+0+0 -resize 160x120>"])
expect(subject.steps[0].arguments).to eq(["123x44+0+0", "160x120>"])
end
end
end
Expand Down
8 changes: 8 additions & 0 deletions spec/support/dragonfly_test_app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

def dragonfly_test_app(name = nil)
app = Dragonfly::App.instance(name)
app.datastore = Dragonfly::MemoryDataStore.new
app.secret = "test secret"
app
end

0 comments on commit acf28b1

Please sign in to comment.