rails mount_uploader images aws ruby-on-rails amazon-s3 carrierwave exif rmagick

ruby-on-rails - mount_uploader - rails image upload



problema de rotación de imágenes exif usando carrierwave y rmagick para cargar en s3 (4)

Bueno, esto funciona usando niebla en su lugar o carrierwave_direct.

A continuación se muestra el código que terminó trabajando para mí:

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

aplicación / modelos / 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

Tengo una función de carga de fotos en mi aplicación de rieles. La aplicación se carga directamente a s3 a través de carrierwave a través de rmagick y fog. El problema que estoy teniendo es cuando una foto se carga a través del móvil a través de la opción "tomar una foto" en el retrato (tenga en cuenta que es con el iPhone, pero creo que Android tiene el mismo problema). Una vez cargada, la imagen aparece bien en el móvil, sin embargo, cuando se ve en el escritorio, la imagen aparece girada 90 grados.

A través de mi investigación, parece ser un problema con exif. Este respondedor stackoverflow delinea 2 soluciones potenciales. Esta gist también parece prometedora.

Hasta ahora he encontrado algunas soluciones publicadas pero ninguna ha funcionado. Idealmente, me gustaría que la foto se guarde en s3 como retrato, y luego solo mostrar la imagen tal como está.

Cualquier sugerencia es muy apreciada.

A continuación está mi código

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

aplicación / modelos / 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

Por cierto, utilicé este Railscast como guía para configurar mi carga s3.


Mi solución (bastante similar a Sumeet):

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

Es realmente importante devolver una imagen. De lo contrario, obtendrás un

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


Tuve un problema similar y lo solucioné con un enfoque casi idéntico al tuyo.

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

(Tenga en cuenta que no estoy llamando auto_orient! - simplemente auto_orient , sin el bang .)

Luego tengo el process :auto_orient como la primera línea de cualquier version que creo. Por ejemplo:

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


La respuesta de Lando2319 no funcionaba para mí.

Estoy usando RMagick.

Pude hacer que ImageMagick aplicara la orientación correcta (y restablecer los datos de rotación EXIF ​​para evitar una rotación doble por parte del espectador) al usar:

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

La diferencia entre mi solución y la de Lando es la explosión (!). En mi caso, fue absolutamente necesario.