add service to rotate jpg attachment automatically
This commit is contained in:
parent
c794f654ea
commit
96238da249
5 changed files with 68 additions and 0 deletions
22
app/models/concerns/attachment_auto_rotate_concern.rb
Normal file
22
app/models/concerns/attachment_auto_rotate_concern.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
module AttachmentAutoRotateConcern
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
after_create_commit :auto_rotate
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def auto_rotate
|
||||
return if blob.nil?
|
||||
return if ["image/jpeg", "image/jpg"].exclude?(blob.content_type)
|
||||
|
||||
blob.open do |file|
|
||||
Tempfile.create(["rotated", File.extname(file)]) do |output|
|
||||
processed = AutoRotateService.new.process(file, output)
|
||||
blob.upload(processed) # also update checksum & byte_size accordingly
|
||||
blob.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
30
app/services/auto_rotate_service.rb
Normal file
30
app/services/auto_rotate_service.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
class AutoRotateService
|
||||
def process(file, output)
|
||||
auto_rotate_image(file, output)
|
||||
output
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def auto_rotate_image(file, output)
|
||||
image = MiniMagick::Image.new(file.to_path)
|
||||
|
||||
case image["%[orientation]"]
|
||||
when 'LeftBottom'
|
||||
rotate_image(file, output, 90)
|
||||
when 'BottomRight'
|
||||
rotate_image(file, output, 180)
|
||||
when 'RightTop'
|
||||
rotate_image(file, output, 270)
|
||||
end
|
||||
end
|
||||
|
||||
def rotate_image(file, output, degree)
|
||||
MiniMagick::Tool::Convert.new do |convert|
|
||||
convert << file.to_path
|
||||
convert.rotate(degree)
|
||||
convert.auto_orient
|
||||
convert << output.to_path
|
||||
end
|
||||
end
|
||||
end
|
|
@ -17,6 +17,7 @@ end
|
|||
ActiveSupport.on_load(:active_storage_attachment) do
|
||||
include AttachmentTitreIdentiteWatermarkConcern
|
||||
include AttachmentVirusScannerConcern
|
||||
include AttachmentAutoRotateConcern
|
||||
end
|
||||
|
||||
Rails.application.reloader.to_prepare do
|
||||
|
|
BIN
spec/fixtures/files/image-rotated.jpg
vendored
Normal file
BIN
spec/fixtures/files/image-rotated.jpg
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
15
spec/services/auto_rotate_service_spec.rb
Normal file
15
spec/services/auto_rotate_service_spec.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
RSpec.describe AutoRotateService do
|
||||
let(:image) { file_fixture("image-rotated.jpg") }
|
||||
let(:auto_rotate_service) { AutoRotateService.new }
|
||||
|
||||
describe '#process' do
|
||||
it 'returns a tempfile if auto_rotate succeeds' do
|
||||
Tempfile.create do |output|
|
||||
auto_rotate_service.process(image, output)
|
||||
expect(MiniMagick::Image.new(image.to_path)["%[orientation]"]).to eq('LeftBottom')
|
||||
expect(MiniMagick::Image.new(output.to_path)["%[orientation]"]).to eq('TopLeft')
|
||||
expect(output.size).to be_between(image.size / 1.2, image.size)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue