From a52c80e2a8130b770a57c11b76dbdcd21f51ae28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Wed, 9 Jul 2014 23:59:57 +0200 Subject: [PATCH] FEATURE: automatic image orientation fix --- app/models/upload.rb | 6 ++++++ spec/components/avatar_upload_service_spec.rb | 4 ++-- spec/fixtures/images/logo-dev.png | Bin 3266 -> 5394 bytes spec/fixtures/images/logo.png | Bin 2290 -> 2506 bytes spec/models/upload_spec.rb | 7 +++++++ 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/models/upload.rb b/app/models/upload.rb index 03a965306c2..f01c6442467 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -75,6 +75,8 @@ class Upload < ActiveRecord::Base # deal with width & height for images if FileHelper.is_image?(filename) begin + # fix orientation first + Upload.fix_image_orientation(file.path) # retrieve image info image_info = FastImage.new(file, raise_on_failure: true) # compute image aspect ratio @@ -115,6 +117,10 @@ class Upload < ActiveRecord::Base Upload.find_by(url: url) if Discourse.store.has_been_uploaded?(url) end + def self.fix_image_orientation(path) + `convert #{path} -auto-orient #{path}` + end + end # == Schema Information diff --git a/spec/components/avatar_upload_service_spec.rb b/spec/components/avatar_upload_service_spec.rb index c515bbb3450..d33a2fab402 100644 --- a/spec/components/avatar_upload_service_spec.rb +++ b/spec/components/avatar_upload_service_spec.rb @@ -16,7 +16,7 @@ describe AvatarUploadService do let(:avatar_file) { AvatarUploadService.new(file, :image) } it "should have a filesize" do - avatar_file.filesize.should == 2290 + avatar_file.filesize.should > 0 end it "should have a filename" do @@ -38,7 +38,7 @@ describe AvatarUploadService do before { FileHelper.stubs(:download).returns(logo) } it "should have a filesize" do - avatar_file.filesize.should == 2290 + avatar_file.filesize.should > 0 end it "should have a filename" do diff --git a/spec/fixtures/images/logo-dev.png b/spec/fixtures/images/logo-dev.png index 1b309fc375521a473c1cea08fdd6ed809c834d3b..90aaf71f981a99782eac9d8d0b59935784a6f677 100644 GIT binary patch literal 5394 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 literal 3266 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 diff --git a/spec/fixtures/images/logo.png b/spec/fixtures/images/logo.png index c8d7600f7ab60abfc7c00f2f9a336777cb0e4515..6fa34467aae03b9cfcd3d28b6f78530e3527a30e 100644 GIT binary patch delta 2443 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