exif图像旋转问题使用carrierwave和rmagick上传到s3

我的rails应用程序中有一个照片上传function。 该应用程序通过rmagick和雾直接通过carrierwave上传到s3。 我遇到的问题是通过手机上的“拍照选项”上传照片时(注意这是iphone,但我相信Android有同样的问题)。 上传后,图像在手机上显示正常,但在桌面上查看时,图像会旋转90度。

通过我的研究,它看起来是exif的一个问题。 此stackoverflow响应程序概述了2个可能的解决方案。 这个要点也看起来很有希望。

到目前为止,我发现了一些解决方案,但没有一个有效。 理想情况下,我希望将照片作为肖像保存到s3,然后按原样显示图像。

任何建议都很受欢迎。

以下是我的代码

应用程序/上传/ 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 

应用程序/模型/ 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 

配置/初始化/ carrierwave.rb

 CarrierWave.configure do |config| config.fog_credentials = { provider: "AWS", aws_access_key_id: " ... ", aws_secret_access_key: " ... " } config.fog_directory = " ... " end 

顺便说一句,我使用这个Railscast作为设置我的s3上传的指南。

好吧,我得到了这个工作使用雾而不是carrierwave_direct。

以下是最终为我工作的代码:

应用程序/上传/ 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 

应用程序/模型/ s3_image.rb

 class S3Image < ActiveRecord::Base attr_accessible :image, :name, :user_id, :image_cache mount_uploader :image, ImageUploader belongs_to :user end 

初始化/ 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 

我遇到了类似的问题并用与你的方法几乎相同的方法修复了它。

 # In the uploader: def auto_orient manipulate! do |img| img = img.auto_orient end end 

(注意我不是在调用auto_orient! – 只是auto_orient ,没有爆炸 。)

然后我有process :auto_orient作为我创建的任何version的第一行。 例如:

 version :square do process :auto_orient process :resize_to_fill => [600, 600] end 

我的解决方案(与Sumeet非常相似):

 # painting_uploader.rb process :right_orientation def right_orientation manipulate! do |img| img.auto_orient img end end 

返回图像非常重要。 否则,你会得到一个

 NoMethodError (undefined method `write' for "":String): 

Lando2319的答案对我不起作用。

我正在使用RMagick。

我设法通过使用以下方法使ImageMagick应用正确的方向(并重置EXIF旋转数据以避免观察者的双重旋转):

 def fix_exif_rotation # put this before any other process in the Carrierwave uploader manipulate! do |img| img.tap(&:auto_orient!) end 

我的解决方案和Lando的区别在于爆炸(!)。 在我看来,这绝对是必要的。