CarrierWaveでCrop処理をする際のversionsについて
下記環境で、アップロードした画像を任意の範囲でcroppingするための処理を実装していたのですが、メインの画像ファイルは意図した通りにcropできました。しかし、versionsでの処理が上手く行かなかったので質問させてください。
- Rails 4.2.1
- CarrierWave 0.10.0
- 試行するためのプロジェクトも公開しています。
詳細
アップロードした画像はversionを[:mobile]として別途processしているのですが、
croppingが適用されません。実現したいのはメインのアップロード画像と併せて[:mobile]バージョンもcroppingしたいのです。
Cropのための記述
app/uploaders/common_uploader.rb
class CommonUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
def cropper
return unless model.send("#{mounted_as}_crop_x").present?
manipulate! do |img|
crop_x = model.image_crop_x.to_i
crop_y = model.image_crop_y.to_i
crop_w = model.image_crop_w.to_i
crop_h = model.image_crop_h.to_i
rotation = model.image_rotate.to_i
crop_value = "#{crop_w}x#{crop_h}+#{crop_x}+#{crop_y}"
img.rotate rotation
img.crop crop_value
img = yield(img) if block_given?
img
end
end
end
app/models/user.rb
uploaders/に記述したcropperメソッド内ではattr_accessorの値が取得できないようです。
(https://stackoverflow.com/questions/17639405/carrierwave-attributes-that-are-not-in-the-database-is-always-equal-to-nil)
なので、他の情報を参考にafter_update時に、croppingメソッドから画像処理を呼び出すようにしました。
class User < ActiveRecord::Base
mount_uploader :image, ::UserImageUploader
attr_accessor :image_crop_x
attr_accessor :image_crop_y
attr_accessor :image_crop_w
attr_accessor :image_crop_h
attr_accessor :image_rotate
after_update :cropping
private
def cropping
if image_crop_x.present?
image.process!
#image.cropper
#image.cache_stored_file!
#image.retrieve_from_cache!(image.cache_name)
#image.recreate_versions!
#image.recreate_versions!
end
end
end
image.process!またはimage.cropperをuser.rb内のcroppingで実行するとcropされます。また、以下のように記述しても可能です。
image.cache_stored_file!
image.retrieve_from_cache!(image.cache_name)
image.recreate_versions!
しかし、app/uploaders/user_image_uploader.rb
に記述している、[:mobile],[:thumb]のバージョンについてはcropできません。
class UserImageUploader < CommonUploader
version :mobile do
end
version :thumb do
process quality: 50
end
end
以上が問題の内容なのですが、image.recreate_versions!
を2度記述するとmobile,thumbのバージョンについてもcropされるようになります。しかし、この場合、外部ストレージの環境(S3など)の際にNoMethodError - undefined method
content_length' for nil:NilClass:`が発生してしまいます。
どのように記述すればよいでしょうか?
よろしくお願いいたします。