未定义的方法裁剪! 在轨道3.1.3上使用Carrierwave和MiniMagick

我有一段时间让这个工作,但仍然是。 我会明白它的核心。 我正在关注Ryan Bates教程,使用Jcrop和Carrierwave进行裁剪工作。 我选择使用MiniMagick,因为即使在我的机器上重新安装ImageMagick和RMagick后,我也会收到一个错误,导致我本地计算机上的rails服务器死机。 无论如何切换到MiniMagick修复了我。 所以到目前为止,一切都非常好。 我生成了不同大小的图像,并且它们已成功上传。 但是一旦我尝试裁剪,我得到这个错误:

undefined method `crop!' for # 

这让我感到困惑,因为我使用的代码与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 

无论如何,这种作物方法失败了。 所以我想,这是一个ImageMagick命令……所以我看了ImageMagick doco,我找不到爆炸的裁剪方法,所以我没试过,然后错误转向:

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

无论如何,有些东西对我来说没什么意义,任何帮助都会受到赞赏! 谢谢阅读!

有同样的问题,我的解决方案是这种方法

 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 

只需根据您的情况修改我的方法。
关键是以哪种格式将变量传递给裁剪方法,希望这对您有所帮助。

简而言之:

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

这里有一个更好的解释为什么发生这种情况而不是剪切/粘贴式解决方案。

RMagick和MiniMagick不可互换。 RMagick有一个非常类似Ruby的DSL,因此使用了带有多个参数的方法:

 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通过迭代MOGRIFY_COMMANDS列表来动态生成方法, 该列表与ImageMagick的mogrify文档中指定的许多带有前缀的选项相匹配。 每个方法都将其参数直接传递给mogrify而没有返回图像对象:

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

实物,RMagick有crop! 而MiniMagick没有。

根据ImageMagick文档, mogrify -crop采用参数geometrygeometry参数在这里解释。 您会注意到所有这些参数都是字符串,因此您将使用crop('100x200')crop('100%)而不是crop(100,200) crop('100%) 。 它不像Ruby那样,但这是MiniMagick如此轻量级的一部分。

有了这些知识,我们就可以推断出如何使用MiniMagick进行裁剪。 mogrify -crop可以将几何体作为字符串width x height + xoffset + yoffset ,因此我们只需要构建一个类似的字符串。

给定whxy您可以使用以下最易读的内容:

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

这是一个完整的例子:

 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 

我可以通过将@和Y参数添加到crop命令来实现此function,如@ mikhail-nikalyukin所示

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