problema di rotazione delle immagini exif utilizzando carrierwave e rmagick per caricare su s3

Ho una funzione di caricamento delle foto nella mia app per i rails. L’app carica direttamente su s3 tramite carrierwave tramite rmagick e fog. Il problema che sto avendo è quando una foto viene caricata tramite cellulare attraverso l’opzione “scatta una foto” in verticale (nota questo è con iphone ma credo che Android abbia lo stesso problema). Una volta caricata, l’immagine viene visualizzata correttamente sul dispositivo mobile, tuttavia, se visualizzata sul desktop, l’immagine viene ruotata di 90 gradi.

Attraverso la mia ricerca sembra essere un problema con exif. Questo risponditore StackOverflow delinea 2 soluzioni potenziali. Anche questo aspetto sembra promettente.

Finora ho trovato alcune soluzioni pubblicate ma nessuna ha funzionato. Idealmente vorrei che la foto venisse salvata su s3 come ritratto, quindi visualizzare solo l’immagine così com’è.

Qualsiasi suggerimento è ben apprezzato.

Di seguito è il mio codice

    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 / modelli / 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 / inizializzatori / carrierwave.rb

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

    btw ho usato questo Railscast come guida per configurare il mio upload s3.

    Beh, ho funzionato usando nebbia invece o carrierwave_direct.

    Di seguito è riportato il codice che ha finito per funzionare per 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 / modelli / s3_image.rb

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

    inizializzatori / 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 

    Ho avuto un problema simile e l’ho risolto con un approccio quasi identico al tuo.

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

    (Nota che non sto chiamando auto_orient! – solo auto_orient , senza il botto .)

    Quindi ho process :auto_orient come prima riga di qualsiasi version che creo. Per esempio:

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

    La mia soluzione (abbastanza simile a Sumeet):

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

    È molto importante restituire un’immagine. Altrimenti, otterrai un

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

    La risposta di Lando2319 non funzionava per me.

    Sto usando RMagick.

    Sono riuscito a fare in modo che ImageMagick applichi l’orientamento corretto (e resetti i dati di rotazione EXIF ​​per evitare una doppia rotazione da parte del visualizzatore) usando:

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

    La differenza tra la mia soluzione e quella di Lando è il botto (!). Nel mio caso era assolutamente necessario.