reprocessing images in Carrierwave

For garmz I’m using the CarrierWave plugin and when I had to implement cropping for the images that are attached to our designs I faced the problem of having to regenerate the various versions based with different cropping values.

The main principle of my solution is to create new images with new ids, path names etc to prevent any photo not being reloaded on the client side. Otherwise I’d have to invalidate the caches, not my thing.

In order to achieve this we create a new Image, assign my cropping parameters and then assign the file from the old Image. For some reasons it looks as if the images are processed once it’s assigned and not when it’s being saved.

In the Controller:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
if images = params[:crop_images]
  images.each do |image_id, crop_data|
    next if crop_data.blank?

    old_file = object.images.find(image_id).asset.file
    new_image = Image.new(:crop => JSON.parse(crop_data).reject{|k,v| !%w(x y h w).include?(k)})
    new_image.asset = old_file

    new_image.write_asset_identifier
    new_image.store_asset!
    object.images << new_image
    object.images.find(image_id).destroy
  end
end
In the model:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class ImageUploader
  version :thumb do
    process! :crop
  end
  def crop
    return if model.crop.blank?
    manipulate! do |img|
      img.crop "%ix%i+%i+%i" % [model.crop["w"], model.crop["h"], model.crop["x"], model.crop["y"]]
    end
  end
end
class Image
  include Mongoid::Document
  field :crop, :type => Hash
  belongs_to :designs
  mount_uploader :asset, ImageUploader
end

Leave a Reply