首页 文章

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

提问于
浏览
25

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

通过我的研究,它看起来是exif的一个问题 . 这个stackoverflow responder概述了2个潜在的解决方案 . 这个gist看起来也很有希望 .

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

任何建议都很受欢迎 .

以下是我的代码

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

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

4 回答

  • 1

    好吧,我使用雾代替或者运行了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
    
  • 33

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

    # 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
    
  • 5

    我的解决方案(与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):
    
  • 15

    Lando2319's answer对我不起作用 .

    我正在使用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的区别在于爆炸(!) . 在我看来,这绝对是必要的 .

相关问题