6

I'm using carrierwave and I have this problem: Suppose once the project has been delivered you need to add a section where the images in the system need to be displayed with a different size. I don' t want to regenerate the new dimension for each one of the images already in the system. I want to be able to generate (and cache it) whenever a view demands. Something like: " /> . If the new size 500x150 already exists, then returns the cached url, else generate it and return the cached url

I like pretty much Carrierwave but unfortunately doesn't have any on the fly resize feature out of the box. Everyone says it should be pretty simple add this feature but I found almost nothing. The only thing which goes pretty close is this uploader https://gist.github.com/DAddYE/1541912 I had to modify it to make it work so here is my version

class ImageUploader < FileUploader
  include CarrierWave::RMagick

  #version :thumb do
  #  process :resize_to_fill => [100,100]
  #end
  #
  #version :thumb_square do
  #  process :resize_to_fill => [100,100]
  #end
  #
  #version :full do
  #  process :resize_to_fit => [550, 550]
  #end


  def re_size(string_size)
    if self.file.nil?
      return self
    end

    begun_at = Time.now
    string_size.gsub!(/#/, '!')
    uploader = Class.new(self.class)
    uploader.versions.clear
    uploader.version_names = [string_size]
    img = uploader.new(model, mounted_as)
    img.retrieve_from_store!(self.file.identifier)
    cached = File.join(CarrierWave.root, img.url)
    unless File.exist?(cached)
      img.cache!(self)

      img.send(:original_filename=, self.file.original_filename)
      size = string_size.split(/x|!/).map(&:to_i)
      resizer = case string_size
                  when /[!]/ then :resize_to_fit
                  # add more like when />/ then ...
                  else :resize_to_fill
                end
      img.send(resizer, *size)
      FileUtils.mv(img.file.file, cached)
      #img.store!
    end
    img
  end

  def extension_white_list
    %w[jpg jpeg gif png]
  end

  def filename
    Digest::MD5.hexdigest(original_filename) << File.extname(original_filename) if original_filename
  end

  def cache_dir
    "#{Rails.root}/tmp/uploads"
  end

  def default_url
    '/general/no-image.png'
  end
end

The problem with this version is that apparently when calling re_size("100x100").url, the url gets generated and returned before the actual resized image is created resulting in a page with broken links which displays good on any subsequent refresh.

Anyone achieved better results willing to share? :)

Please don't tell me to switch to Dragonfly. I'm using Carrierwave and i really like it. Also it seamlessly integrates with RailsAdmin which is part of my projects too.

Vincent Robert
  • 35,564
  • 14
  • 82
  • 119
user711643
  • 297
  • 2
  • 18

1 Answers1

0

Why don't you just generate a different version of the image, such as a thumbnail? In your image_uploader.rb

 # Create different versions of your uploaded files:

 include CarrierWave::RMagick


 version :thumb do
    process :resize_to_limit => [100, 100]
 end

Then in your view just call

 <%= image_tag nameofimage.image_url(:thumb).to_s %>

You could create multiple versions of our original image without resizing the original image. The processing is done by RMagick which you'll need to install.

RMagick requires you to have ImageMagick, so you'll need to install that as well. These can be a little tricky to get installed and working but well worth it. Plus the stackoverflow community has provided a lot of help with this issue.

Error installing Rmagick on Mountain Lion

rmagick gem install "Can't find Magick-config"

Community
  • 1
  • 1
ChrisBarthol
  • 4,871
  • 2
  • 21
  • 24
  • Problem is most of the times design is very poor and I don't know the exact images dimensions ahead of development resulting in endless regeneration of resized images each time a new size is added or discovered. I need a way to generate on the fly – user711643 Oct 11 '13 at 08:29
  • The above takes your original image, regardless of dimensions, and sizes it to the specified dimension limits. I don't know what you mean by 'on the fly'. – ChrisBarthol Oct 11 '13 at 15:16
  • 1
    I mean on-demand. Suppose once the project has been delivered you need to add a section where the images in the system need to be displayed with a different size. I don' t want to regenerate the new dimension for each one of the images already in the system. I want to be able to generate (and cache it) whenever a view demands. Something like: " /> . If the new size 500x150 already exists, then returns the cached url, else generate it and return the cached url – user711643 Oct 12 '13 at 10:36