Rotaie: ritaglio delle immagini con graffetta, S3 e RMagick
-
05-07-2019 - |
Domanda
Attualmente sto cercando di codificare un sistema di ritaglio di immagini personalizzato simile ad altri su Internet in cui un utente può selezionare un'area di ritaglio e quindi ritagliare l'immagine di conseguenza. L'applicazione è in Rails e stiamo usando Paperclip con Amazon S3 per archiviare i file. Ho molti problemi anche se sto facendo in modo che RMagick ritagli correttamente il file da S3. Ecco il codice corrente (che non funziona):
if params[:width].to_i > 0 and params[:height].to_i > 0 then
photo = Photo.find(params[:id])
image_data = Net::HTTP.get_response(URI.parse(photo.photo.url(:big))).body
orig_img = Magick::ImageList.new
orig_img.from_blob(image_data)
args = [params[:x1].to_i, params[:y1].to_i, params[:width].to_i, params[:height].to_i]
orig_img.crop!(*args)
photo.update_attributes({:photo => orig_img.to_blob})
photo.photo.reprocess!
photo.save
end
Il problema principale è che l'immagine ritagliata non viene ricaricata su S3 tramite graffetta e quindi non ritagliata correttamente. Qualcuno ha mai provato qualcosa del genere con una graffetta prima? Ciò potrebbe anche non essere possibile, ma qualsiasi aiuto sarebbe molto apprezzato.
Soluzione
Sono stato in grado di risolvere questo problema per il momento come segue:
photo = Photo.find(params[:id])
image_data = Net::HTTP.get_response(URI.parse(photo.photo.url(:big))).body
orig_img = Magick::ImageList.new
orig_img.from_blob(image_data)
args = [params[:x1].to_i, params[:y1].to_i, params[:width].to_i, params[:height].to_i]
orig_img.crop!(*args)
tmp_img = Tempfile.new("image_data")
orig_img.format = "png"
tmp_img.write(orig_img.to_blob)
photo.photo = tmp_img
tmp_img.close
photo.photo.reprocess!
photo.save
La preoccupazione principale qui è la velocità della creazione di un nuovo file temporaneo, quindi probabilmente dovremo creare la nostra interfaccia personalizzata. Spero che questo possa essere un buon punto di partenza per le persone che risolvono un problema simile.
EDIT: solo una breve nota, Tempfile fa parte delle librerie di graffette.
Altri suggerimenti
È possibile definire alcuni attr_accessors sul modello e impostarli nell'azione del controller prima di creare il file effettivo. Di seguito dovrebbe funzionare ..
class Poodle < ActiveRecord::Base
has_attached_file :avatar, :styles => Proc.new{|a| a.instance.get_styles}
attr_accessor :width, :height
def get_styles(style = "medium")
return {style.to_sym => [self.width, self.height].join("x") + ">" }
end
end
Potresti dare un'occhiata più da vicino a Processori per graffette .
In realtà ho lo stesso problema nel mio codice e lo ho nella mia lista di cose da fare.