exif image rotation issue using carrierwave and rmagick to upload to s3
Solution 1
Well I got this working using fog instead or carrierwave_direct.
Below is the code that ended up working for me:
app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def fix_exif_rotation #this is my attempted solution
manipulate! do |img|
img.tap(&:auto_orient)
end
end
process :fix_exif_rotation
end
app/models/s3_image.rb
class S3Image < ActiveRecord::Base
attr_accessible :image, :name, :user_id, :image_cache
mount_uploader :image, ImageUploader
belongs_to :user
end
initializers/carrierwave.rb
CarrierWave.configure do |config|
config.fog_credentials = {
provider: "AWS",
aws_access_key_id: " ... ",
aws_secret_access_key: " ... ",
region: 'us-west-2'
}
config.fog_directory = " ... "
end
Solution 2
I had a similar problem and fixed it with an approach nearly identical to yours.
# In the uploader:
def auto_orient
manipulate! do |img|
img = img.auto_orient
end
end
(Note that I am not calling auto_orient!
- just auto_orient
, without the bang.)
Then I have process :auto_orient
as the first line of any version
I create. For example:
version :square do
process :auto_orient
process :resize_to_fill => [600, 600]
end
Solution 3
My solution (quite similar to Sumeet) :
# painting_uploader.rb
process :right_orientation
def right_orientation
manipulate! do |img|
img.auto_orient
img
end
end
It's really important to return an image. Otherwise, you'll get an
NoMethodError (undefined method `write' for "":String):
Solution 4
Lando2319's answer was not working for me.
I am using RMagick.
I managed to make ImageMagick apply the correct orientation (and to reset the EXIF rotation data in order to avoid a double rotation by the viewer) by using :
def fix_exif_rotation # put this before any other process in the Carrierwave uploader
manipulate! do |img|
img.tap(&:auto_orient!)
end
The difference between my solution & Lando's is the bang (!). In my case it was absolutely necessary.
lando2319
Co-Founder | CTO at ChangEd Software Dev, Swift, JS, Kotlin Curious, Vim Fanatic
Updated on June 05, 2022Comments
-
lando2319 almost 2 years
I've got a photo upload feature in my rails app. The app uploads direct to s3 through carrierwave via rmagick and fog. The issue I am having is when a photo is uploaded via mobile through the "take a photo option" in portrait (note this is with iphone but I believe android has the same issue). Once uploaded the image appears fine on mobile, however when viewed on desktop the image appears rotated 90 degrees.
Through my research it looks to be an issue with exif. This stackoverflow responder outlines 2 potential solutions. This gist also looks promising as well.
So far I have found a few solutions posted but none have worked. Ideally I would like the photo to be saved to s3 as a portrait, then just display the image as is.
Any suggestions are well appreciated.
Below is my code
app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base include CarrierWaveDirect::Uploader include CarrierWave::RMagick # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility: include Sprockets::Helpers::RailsHelper include Sprockets::Helpers::IsolatedHelper include CarrierWave::MimeTypes process :fix_exif_rotation process :set_content_type version :thumb do process resize_to_fill: [200, 200] end def extension_white_list %w(jpg jpeg png) end def fix_exif_rotation #this is my attempted solution manipulate! do |img| img = img.auto_orient! end end end
app/models/s3_image.rb
class S3Image < ActiveRecord::Base attr_accessible :image, :name, :user_id mount_uploader :image, ImageUploader belongs_to :user def image_name File.basename(image.path || image.filename) if image end class ImageWorker include Sidekiq::Worker def perform(id, key) s3_image = S3Image.find(id) s3_image.key = key s3_image.remote_image_url = s3_image.image.direct_fog_url(with_path: true) s3_image.save! s3_image.update_column(:image_processed, true) end end end
config/initializers/carrierwave.rb
CarrierWave.configure do |config| config.fog_credentials = { provider: "AWS", aws_access_key_id: " ... ", aws_secret_access_key: " ... " } config.fog_directory = " ... " end
btw I used this Railscast as a guide for setting up my s3 upload.
-
lando2319 over 10 yearsThank you for the suggestion, unfortunately this didn't fix my issue.
-
benizi over 10 years@JonathanAllard the
manipulate!
block wants an image, butimage.auto_orient
returns an empty string.image.tap(&:auto_orient)
roughly corresponds toimage.auto_orient ; image
. -
wuliwong about 10 yearsI added this to my versions then recreated the versions and it has fixed the sideways image issues. So far I've only tested it with images uploaded via safari on ios 7. hopefully it works across the board. thanks.
-
user664833 over 9 yearsYour solution worked for me, whereas @Sumeet's did not, despite how similar. Also, thanks for the tip about the need to return an image. For the record, I had a similar error
NoMethodError (undefined method 'destroy!' for "":String)
. -
Sandro L about 8 yearsWorked for me only when using
img.tap(&:auto_orient!)
(note the bang!). But I am also usingCarrierWave::RMagick
instead ofCarrierWave::MiniMagick
-
jcuervo over 7 yearsSumeet's solution only works for the versions. The uploaded original image is still rotated. This solution from @lando2319 works for both the original image and the thumbnails.
-
hoitomt over 7 yearsI needed to add the bang as well
img.tap(&:auto_orient!)
. Thanks for thefix_exif_rotation
method. -
Hafiz Abdul Rehman over 2 yearsI was also facing the same issue using RMagick with iPhone images which got fixed as I call it at the start of my
name_uploaded.rb
file afterinclude CarrierWave::ImageRounder
like thisprocess :fix_exif_rotation