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

cou*_*ing 17 ruby-on-rails carrierwave minimagick

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

undefined method `crop!' for #<MiniMagick::CommandBuilder:0x000001052e4608>
Run Code Online (Sandbox Code Playgroud)

这让我感到困惑,因为我使用的代码与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
Run Code Online (Sandbox Code Playgroud)

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

No such file or directory - /var/folders/dF/dFNM2+Y7FVScn4+OxVHKOU+++TI/-Tmp-/mini_magick20111207-34409-1tnaa07.jpg
Run Code Online (Sandbox Code Playgroud)

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

fny*_*fny 48

简而言之:

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

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

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
Run Code Online (Sandbox Code Playgroud)

相反,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`
Run Code Online (Sandbox Code Playgroud)

实物,RMagick crop!和MiniMagick没有.

根据ImageMagick文档,mogrify -crop进行论证geometry.这里geometry解释这个论点.您会注意到所有这些参数都是字符串,因此crop(100,200)您不会使用crop('100x200')crop('100%).它不像Ruby那样,但这是MiniMagick如此轻量级的一部分.

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

鉴于w,h,x,和y你可以使用的任何下面你会发现最可读的:

# 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}"
Run Code Online (Sandbox Code Playgroud)

这是一个完整的例子:

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
Run Code Online (Sandbox Code Playgroud)


Mik*_*kin 15

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

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
Run Code Online (Sandbox Code Playgroud)

只需根据您的情况修改我的方法.
关键是以哪种格式传递变量到crop方法,希望这对你有所帮助.

  • 只是添加......这是我从米哈伊尔的代码中所做的.重要的是(正如他正确指出的那样)是(1)用`crop`替换`crop!`并在`manipulate!`块的末尾返回图像,否则你会出现写错误.` `ruby def crop if model.crop_x.present?resize_to_limit(600,600)操纵!做| 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("#{w} x#{h} +#{x} +#{y }")img end end end``` (3认同)