17

私はこれを機能させるのにかなりの時間を費やしていましたが、今でもそうです。その核心に迫ります。私は Ryan Bates のチュートリアルに従って、Jcrop と Carrierwave を使用してクロッピングを機能させています。ImageMagick と RMagick をマシンに再インストールした後でも、ローカル マシンの Rails サーバーを強制終了するエラーが発生するため、MiniMagick を使用することにしました。とにかくMiniMagickに切り替えると、それが修正されました。したがって、この時点まではすべてが本当に素晴らしいです。さまざまなサイズの画像を作成していますが、正常にアップロードされています。しかし、トリミングしようとすると、次のエラーが発生します。

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

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

とにかく、何かが私にはあまり意味がありません。どんな助けもいただければ幸いです! 読んでくれてありがとう!

4

3 に答える 3

48

要するに:

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は、 ImageMagick のドキュメントで指定されている多数のダッシュ接頭辞付きオプションと一致するリストを反復処理することにより、MOGRIFY_COMMANDS動的にメソッドを生成します。これらの各メソッドは引数を直接渡しますが、画像オブジェクトを返すものはありません。mogrifymogrify

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 docs によるとmogrify -crop、引数を取りますgeometry。ここでgeometry引数 を 説明 します. これらの引数はすべて文字列であるため、代わりにorcrop(100,200)を使用することに気付くでしょう。Ruby にあまり似ていませんが、それが MiniMagick を非常に軽量にしている理由の 1 つです。crop('100x200')crop('100%)

その知識があれば、MiniMagick でトリミングする方法を推測できます。mogrify -cropはジオメトリを文字列widthx height+ xoffset+yoffsetとして受け取ることができるため、同様の文字列を構築するだけで済みます。

whxを指定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}"

完全な例を次に示します。

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
于 2012-04-01T02:25:51.000 に答える
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

あなたのケースに合わせて私の方法を変更してください。
重要なのは、どの形式で変数をクロップ メソッドに渡すかです。これがお役に立てば幸いです。

于 2011-12-07T16:56:06.637 に答える
2

@ mikhail-nikalyukinで示されているように、XおよびYパラメーターをcropコマンドに追加することで、これを機能させることができました

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

    img = yield(img) if block_given?
    img
  end
end
于 2012-01-23T22:34:01.700 に答える