Crop de méthode non définie! Utilisation de porte-avions avec minimagick sur les rails 3.1.3

StackOverflow https://stackoverflow.com/questions/8418973

Question

J'avais un sacré temps pour que cela fonctionne, et je le suis toujours. Je vais en arriver au cœur. Je suis le tutoriel Ryan Bates pour faire du travail de recadrage en utilisant JCROP et Carrierwave. J'ai choisi d'utiliser Minimagick car même après avoir réinstallé ImageMagick et Rmagick sur ma machine, je reçois une erreur qui tue le serveur Rails sur ma machine locale. Quoi qu'il en soit, le passage à Minimagick a corrigé cela pour moi. Donc, tout est vraiment bien jusqu'à ce point. J'ai des images de différentes tailles produites et elles sont téléchargées avec succès. Mais une fois que j'essaie de recadrer, je reçois cette erreur:

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

Cela déroutait le diable de moi parce que j'utilise à peu près exactement le même code 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

Quoi qu'il en soit, c'est cette méthode de récolte qui échoue. Alors je me suis dit, c'est une commande ImageMagick ... alors j'ai regardé le Doco ImageMagick, et je n'ai pas trouvé la méthode de recadrage avec le Bang, alors je l'ai essayé sans, puis l'erreur se tourne à ceci:

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

Quoi qu'il en soit, quelque chose n'a pas beaucoup de sens pour moi, toute aide serait appréciée! Merci d'avoir lu!

Était-ce utile?

La solution

Avait les mêmes problèmes, ma solution était cette méthode

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

Modifiez simplement ma méthode pour votre cas.
La clé est dans quel format passe les variables à la méthode de recadrage, j'espère que cela vous aide.

Autres conseils

Bref:

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

Voici une meilleure explication de Pourquoi Cela s'est produit par opposition à une solution de style coupe / pâte.

Rmagick et Minimagick ne sont pas interchangeables. RMAGICK a un DSL très rubis et, en tant que tel, utilise des méthodes qui prennent plusieurs arguments:

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 génère plutôt dynamiquement des méthodes par itérer à travers une liste de MOGRIFY_COMMANDS qui correspondent à de nombreuses options préfixées par tableau de bord spécifiées dans ImageMagick's mogrify Documentation. Chacune de ces méthodes transmet ses arguments directement à mogrify et aucun ne renvoie un objet d'image:

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

En nature, Rmagick a crop! Et Minimagick ne le fait pas.

Selon les documents ImageMagick, mogrify -crop prend un argument geometry. La geometry L'argument est expliqué ici. Tu remarques que tout de ces arguments sont des chaînes, donc au lieu de crop(100,200) vous utiliseriez crop('100x200') ou crop('100%). Ce n'est pas très semblable à un rubis, mais cela fait partie de ce qui rend Minimagick si léger.

Avec ces connaissances, nous pouvons déduire comment recadrer avec Minimagick. mogrify -crop peut prendre une géométrie comme une chaîne widthXheight+xoffset+yoffset, nous avons donc juste besoin de construire une chaîne similaire.

Donné w,h,x, et y Vous pouvez utiliser quel que soit le suivant, vous trouvez le plus lisible:

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

Voici un exemple complet:

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

J'ai pu faire fonctionner cela en ajoutant les paramètres X et Y à la commande CROP comme indiqué par @ mikhail-nikalyukin

def crop
  manipulate! do |img|
    img.crop "750x600+0+0"
    img.strip

    img = yield(img) if block_given?
    img
  end
end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top