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.