【问题标题】:exif image rotation issue using carrierwave and rmagick to upload to s3使用carrierwave和rmagick上传到s3的exif图像旋转问题
【发布时间】:2013-09-02 08:55:24
【问题描述】:

我的 rails 应用中有照片上传功能。该应用程序通过rmagick 和fog 通过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 上传的指南。

【问题讨论】:

    标签: ruby-on-rails amazon-s3 carrierwave exif rmagick


    【解决方案1】:

    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
    

    我的解决方案与兰多的解决方案之间的区别在于爆炸(!)。就我而言,这是绝对必要的。

    【讨论】:

    • 我在使用带有 iPhone 图像的 RMagick 时也遇到了同样的问题,我在include CarrierWave::ImageRounder 之后的name_uploaded.rb 文件的开头调用它,就像这样process :fix_exif_rotation
    【解决方案2】:

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

    【讨论】:

    • 您的解决方案对我有用,而 @Sumeet 的没有,尽管非常相似。另外,感谢关​​于需要返回图像的提示。作为记录,我有一个类似的错误NoMethodError (undefined method 'destroy!' for "":String)
    【解决方案3】:

    好吧,我使用雾代替或carrierwave_direct 来完成这项工作。

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

    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
    

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

    【讨论】:

    • @JonathanAllard manipulate! 块需要图像,但 image.auto_orient 返回一个空字符串。 image.tap(&amp;:auto_orient) 大致对应image.auto_orient ; image
    • 仅在使用 img.tap(&amp;:auto_orient!) 时为我工作(注意爆炸声!)。但我也使用CarrierWave::RMagick 而不是CarrierWave::MiniMagick
    • Sumeet 的解决方案仅适用于这些版本。上传的原始图像仍在旋转。 @lando2319 的这个解决方案适用于原始图像和缩略图。
    • 我还需要添加刘海img.tap(&amp;:auto_orient!)。感谢fix_exif_rotation 方法。
    【解决方案4】:

    我遇到了类似的问题,并用与您几乎相同的方法解决了它。

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

    (请注意,我没有打电话给auto_orient! - 只是auto_orient,没有bang。)

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

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

    【讨论】:

    • 感谢您的建议,不幸的是,这并没有解决我的问题。
    • 我将此添加到我的版本中,然后重新创建了版本,它修复了横向图像问题。到目前为止,我只使用通过 safari 在 ios 7 上上传的图像对其进行了测试。希望它可以全面工作。谢谢。
    猜你喜欢
    • 2012-07-08
    • 2016-06-02
    • 2015-03-30
    • 2018-10-12
    • 2012-06-19
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 2017-01-09
    相关资源
    最近更新 更多