Crop di metodo indefinito! Utilizzando CarrierWave con minimagick sui binari 3.1.3
-
29-10-2019 - |
Domanda
Stavo avendo un sacco di tempo a farlo funzionare, e lo sono ancora. Ci arriverò al cuore. Sto seguendo il tutorial di Ryan Bates per far funzionare il ritaglio usando JCrop e CarrierWave. Ho deciso di usare Minimagick perché anche dopo aver reinstallato ImageMagick e Rmagick sulla mia macchina ricevo un errore che uccide il server Rails sulla mia macchina locale. Comunque, il passaggio a Minimagick ha risolto quello per me. Quindi tutto è davvero bello fino a questo punto. Ho prodotto immagini di dimensioni diverse e vengono caricate con successo. Ma una volta che provo a ritagliare ricevo questo errore:
undefined method `crop!' for #<MiniMagick::CommandBuilder:0x000001052e4608>
Questo mi confonde il diavolo perché sto usando praticamente lo stesso codice di Bates:
def crop
if model.crop_x.present?
resize_to_limit(700, 700)
manipulate! do |img|
x = model.crop_x.to_i
y = model.crop_y.to_i
w = model.crop_w.to_i
h = model.crop_h.to_i
img.crop!(x, y, w, h)
end
end
end
Ad ogni modo, è quel metodo del raccolto che sta fallendo. Così ho pensato a me stesso, questo è un comando ImageMagick ... quindi ho guardato il dimo dimagemagick, e non sono riuscito a trovare il metodo del raccolto con il botto, quindi l'ho provato senza, e poi l'errore si gira a questo:
No such file or directory - /var/folders/dF/dFNM2+Y7FVScn4+OxVHKOU+++TI/-Tmp-/mini_magick20111207-34409-1tnaa07.jpg
Ad ogni modo, qualcosa non sta dando molto senso per me, qualsiasi aiuto sarebbe apprezzato! Grazie per aver letto!
Soluzione
Aveva gli stessi problemi, la mia soluzione era questo metodo
def cropped_image(params)
image = MiniMagick::Image.open(self.image.path)
crop_params = "#{params[:w]}x#{params[:h]}+#{params[:x]}+#{params[:y]}"
image.crop(crop_params)
image
end
Basta modificare il mio metodo per il tuo caso.
La chiave è in cui il formato passa variabili al metodo delle colture, spero che questo ti aiuti.
Altri suggerimenti
In breve:
img.crop("#{size}#{offset}") # Doesn't return an image...
img # ...so you'll need to call it yourself
Ecco una spiegazione migliore di perché Ciò è accaduto rispetto a una soluzione di stile tagliato/in pasta.
Rmagick e Minimagick non sono intercambiabili. Rmagick ha un DSL molto simile a un rubino e come tale impiega metodi che richiedono molteplici argomenti:
rmagick_image.crop(x_offset, y_offset, width, height) # Returns an image object
rmagick_image.crop!(x_offset, y_offset, width, height) # Edits object in place
Minimagick genera invece dinamicamente metodi di iterato attraverso un elenco di MOGRIFY_COMMANDS
che corrispondono a numerose opzioni prefissate da cruscotto specificate in ImageMagick's mogrify
documentazione. Ciascuno di questi metodi trasmette direttamente i loro argomenti mogrify
e nessuno restituisce un oggetto immagine:
minimagick_image.crop('100x200') # Translates to `mogrify -crop 100x200 image.ext`
minimagick_image.polaroid('12') # Executes `mogrify -polaroid 12 image.ext`
In natura, Rmagick ha crop!
E minimagick no.
Secondo i documenti di ImageMagick, mogrify -crop
prende una discussione geometry
. Il geometry
L'argomento è spiegato qui. Lo noterai tutto di questi argomenti sono stringhe, quindi invece di crop(100,200)
useresti crop('100x200')
o crop('100%)
. Non è molto simile a un rubino, ma fa parte di ciò che rende Minimagick così leggero.
Con questa conoscenza, possiamo dedurre come ritagliare con Minimagick. mogrify -crop
può prendere una geometria come stringa width
Xheight
+xoffset
+yoffset
, quindi dobbiamo solo costruire una stringa simile.
Dato w
,h
,x
, e y
Potresti usare qualunque cosa di quanto segue trovi più leggibile:
# Concatenating plus signs with plus signs is atrociously confusing.
# Recommended only if you want to drive your future self insane.
mogrify_arg = w + 'x' + h + '+' + x + '+' + y
# Readable but inefficient
mogrify_arg = [ w, 'x', h, '+', x, '+', y ].join('')
# Questionable readability
mogrify_arg = "#{w}x#{h}+#{x}+#{y}"
# Slick, performant, but potentially risky: `<<` modifies the receiving object in place
# `w` is actually changing here to "WxH+X+Y"...
mogrify_arg = w << 'x' << h << '+' << x << '+' << y
# A lovely, self-documenting version
size = w << 'x' << h
offset = '+' << x '+' << y
mogrify_arg = "#{size}#{offset}"
Ecco un esempio completo:
def crop
if model.crop_x.present?
resize_to_limit(700, 700)
manipulate! do |img|
x = model.crop_x
y = model.crop_y
w = model.crop_w
h = model.crop_h
size = w << 'x' << h
offset = '+' << x << '+' << y
img.crop("#{size}#{offset}") # Doesn't return an image...
img # ...so you'll need to call it yourself
end
end
end
Sono stato in grado di farlo funzionare aggiungendo i parametri X e Y al comando Crop come indicato da @Mikhail-Nikalyukin
def crop
manipulate! do |img|
img.crop "750x600+0+0"
img.strip
img = yield(img) if block_given?
img
end
end