with tutorial rails image_tag aws active ruby-on-rails carrierwave minimagick

ruby on rails - tutorial - Método indefinido de cultivo! Uso de Carrierwave con MiniMagick sobre rieles 3.1.3



rails carrierwave image_tag (3)

Me estaba costando muchísimo conseguir que esto funcionara, y todavía lo soy. Llegaré al corazón de ello. Estoy siguiendo el tutorial de Ryan Bates para hacer que el recorte funcione con Jcrop y Carrierwave. Opté por utilizar MiniMagick porque incluso después de reinstalar ImageMagick y RMagick en mi máquina, aparece un error que destruye el servidor de rieles en mi máquina local. De todos modos cambiando a MiniMagick me lo arreglé. Así que todo está muy bien hasta este punto. Se están produciendo imágenes de diferentes tamaños y se están cargando con éxito. Pero una vez que intento recortar me sale este error:

undefined method `crop!'' for #<MiniMagick::CommandBuilder:0x000001052e4608>

Esto me confunde mucho porque estoy usando casi el mismo código que 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

De todos modos, es ese método de cultivo el que está fallando. Así que pensé, ese es un comando de ImageMagick ... Entonces miré el doco de ImageMagick, y no pude encontrar el método de recorte con la explosión, así que lo intenté sin él, y luego el error se convierte en esto:

No such file or directory - /var/folders/dF/dFNM2+Y7FVScn4+OxVHKOU+++TI/-Tmp-/mini_magick20111207-34409-1tnaa07.jpg

De todos modos, algo no tiene mucho sentido para mí, ¡cualquier ayuda sería apreciada! ¡Gracias por leer!


En breve:

img.crop("#{size}#{offset}") # Doesn''t return an image... img # ...so you''ll need to call it yourself

Aquí hay una mejor explicación de por qué sucedió esto en lugar de una solución de estilo cortar / pegar.

RMagick y MiniMagick no son intercambiables. RMagick tiene un DSL muy parecido a Ruby y, como tal, emplea métodos que toman múltiples argumentos:

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 en su lugar genera dinámicamente métodos al iterar a través de una lista de MOGRIFY_COMMANDS que coinciden con numerosas opciones con prefijo de guión especificadas en la documentación de mogrify de ImageMagick . Cada uno de esos métodos pasa sus argumentos directamente a mogrify y ninguno devuelve un objeto de imagen:

minimagick_image.crop(''100x200'') # Translates to `mogrify -crop 100x200 image.ext` minimagick_image.polaroid(''12'') # Executes `mogrify -polaroid 12 image.ext`

En especie, RMagick tiene crop! y MiniMagick no lo hace.

De acuerdo con los documentos de ImageMagick, mogrify -crop toma una geometry argumento. El argumento de la geometry se explica here . Notará que todos esos argumentos son cadenas, por lo que en lugar de crop(100,200) usaría crop(''100x200'') o crop(''100%) . No es muy parecido a Ruby, pero eso es parte de lo que hace que MiniMagick sea tan liviano.

Con ese conocimiento, podemos deducir cómo recortar con MiniMagick. mogrify -crop puede tomar una geometría como un width cadena x height + xoffset + yoffset , por lo que solo necesitamos construir una cadena similar.

Teniendo en cuenta w , h , x , puede usar cualquiera de las siguientes opciones que encuentre más legibles:

# 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}"

Aquí hay un ejemplo 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


Pude hacer que esto funcionara al agregar los parámetros X e Y al comando de recorte como lo indica @ mikhail-nikalyukin

def crop manipulate! do |img| img.crop "750x600+0+0" img.strip img = yield(img) if block_given? img end end


Tenía los mismos problemas, mi solución fue este método.

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

Solo modifica mi método para tu caso.
La clave está en qué formato pasan las variables al método de recorte, espero que esto le ayude.