Cloudinary Blog

Advanced image transformations in the cloud with CarrierWave & Cloudinary

By Nadav Soferman
In a previous post we've shown how you can easily manage your Ruby on Rails image uploads with CarrierWave and Cloudinary. Many of our Rails readers found this very useful, as it depicted a powerful image management solution that is trivial to integrate - use the popular CarrierWave GEM together with the Cloudinary GEM, add a single 'include' line to your code and that's it. All your images are automatically uploaded to the cloud and delivered through a fast CDN. Better yet, all image transformations defined in your CarrierWave uploader class are generated in the cloud by Cloudinary. No need to install and setup any image processing library (goodbye RMagick, ImageMagick, GraphicsMagick, MiniMagick, etc.). You also don't need to worry any more about CPU power, storage space, image syncing between multiple servers, backup and scale.
 
In this post, we wanted to show how you can use all of Cloudinary's additional cool image management and transformation features together with CarrierWave - apply effects and filters, face detection based cropping, JPG quality modification, adding watermarks and more.
 

Custom and dynamic transformations 

Cloudinary's plugin for CarrierWave supports all of CarrierWave's standard resize and cropping capabilities. In addition, you can apply any custom transformation supported by Cloudinary by using the cloudinary_transformation method. You can call cloudinary_transformation in conjunction with the standard resize and crop methods. 
 
The following uploader class shows a common usage example with custom transformations:
Copy to clipboard
class PictureUploader < CarrierWave::Uploader::Base
  include Cloudinary::CarrierWave

  # Generate a 164x164 JPG of 80% quality 
  version :simple do
    process :resize_to_fill => [164, 164, :fill]
    process :convert => 'jpg'
    cloudinary_transformation :quality => 80
  end

  # Generate a 100x150 face-detection based thumbnail,
  # round corners with a 20-pixel radius and increase brightness by 30%.
  version :bright_face do
    cloudinary_transformation :effect => "brightness:30", :radius => 20,
        :width => 100, :height => 150, :crop => :thumb, :gravity => :face
  end

end
 

Chained Transformations 

You can take this further by applying chained transformations. Any set of transformations can be applied as an incoming transformation while uploading or as part of the different versions that are generated lazily or eagerly during upload. 
 
The following uploader class includes chained transformations applied using the transformation parameter of the cloudinary_transformation method.
Copy to clipboard
class PictureUploader < CarrierWave::Uploader::Base      
  include Cloudinary::CarrierWave
 
  # Apply an incoming chained transformation: limit image to 1000x1200 and 
  # add a 30-pixel watermark 5 pixels from the south east corner.   
  cloudinary_transformation :transformation => [
      {:width => 1000, :height => 1200, :crop => :limit}, 
      {:overlay => "my_watermark", :width => 30, :gravity => :south_east, 
       :x => 5, :y => 5}
    ]        
  
  # Eagerly transform image to 150x200 with a sepia effect applied and then
  # rotate the resulting image by 10 degrees. 
  version :rotated do
    eager
    cloudinary_transformation :transformation => [
        {:width => 150, :height => 200, :crop => :fill, :effect => "sepia"}, 
        {:angle => 10}
      ]
  end
end
Some websites have a graphic design that forces them to display the same images in many different dimensions. Formally defining multiple uploader's versions might become cumbersome. In this case, you can still utilize CarrierWave while leveraging Cloudinary's dynamic transformations by applying any desired transformation while building your view. 
 
Any version can be generated dynamically from your view without depending on CarrierWave versions. Simply use the full_public_id attribute with cl_image_tag to build cloud-based transformation URLs for the uploaded images attached to your model.
Copy to clipboard
cl_image_tag(post.picture.full_public_id, :format => "jpg", 
             :width => 100, :height => 200:crop => :crop, 
             :x => 20, :y => 30, :radius => 10)


Custom coordinates based cropping

If you allow your users to manually select their images cropping areas, we recommend you keep these crop coordinates persistently in your model. This way you'll be able to crop the original images differently in the future. 
 
The following uploader class fetches the custom coordinates from attributes of the model object. The custom_crop method in this example simply returns a Hash of additional Cloudinary transformation parameters to apply.
Copy to clipboard
class PictureUploader < CarrierWave::Uploader::Base  
  include Cloudinary::CarrierWave  
 
  version :full do    
    process :convert => 'jpg'
    process :custom_crop
  end    
  
  def custom_crop      
    return :x => model.crop_x, :y => model.crop_y, 
      :width => model.crop_width, :height => model.crop_height, :crop => :crop      
  end
end
If you want to store only the cropped version of the image, you can use the incoming transformation of Cloudinary's upload API. This way only the cropped image is stored in the cloud. You can then use additional transformations to resize the cropped image. 
 
The following example calls process :custom_crop in the class itself, instead of in a 'version', while the custom-coordinates are kept as transient attributes on the model (defined with attr) instead of storing them persistently.
Copy to clipboard
class PictureUploader < CarrierWave::Uploader::Base  
  include Cloudinary::CarrierWave  
 
  process :custom_crop
 
  version :thumbnail do    
    process :convert => 'jpg'
    resize_to_fill(120, 150, 'North')
  end    
  
  def custom_crop      
    return :x => model.crop_x, :y => model.crop_y, 
      :width => model.crop_width, :height => model.crop_height, :crop => :crop      
  end
end


Private images and eager transformations 

Cloudinary supports uploading private images to the cloud. These images won't be accessible to your users. See our blog post for more details. Together with the Strict Transformations feature, you can specify that only certain transformations (e.g., low resolution thumbnails, watermarked images) are available for your users.
 
For uploading images as private, simply add 'make_private' to your uploader class. This will also make all generated delivery URLs to access the private images correctly. 
 
The versions you define in your uploader class should use only named or dynamic transformations marked as Allowed. Alternatively, you can tell Cloudinary to eagerly generate all transformed versions while uploading. This way you can keep all your transformations as strict (disallowed).
 
The following uploader class shows how to use private images and eager transformations:
Copy to clipboard
class PictureUploader < CarrierWave::Uploader::Base      
  include Cloudinary::CarrierWave
  make_private
  
  # Generate a 164x164 JPG of 80% quality 
  version :simple do
    process :resize_to_fill => [164, 164, :fill]
    process :convert => 'jpg'
    cloudinary_transformation :quality => 80
    eager
  end
  
  version :thumbnail do
    resize_to_fit(50, 50)
    eager
  end
 
end


Summary

If you are a Ruby on Rails developer, you should definitely consider using CarrierWave (if you haven't done so already). Together with Cloudinary you can reach a powerful image management, transformation and delivery solution with almost zero efforts and code changes.
 
If you're looking for a CarrierWave alternative, make sure you check out the brand new Attachinary Ruby GEM. Attachinary provides a modern image attachment solution to your Rails application while employing Cloudinary for cloud-based storage, image transformations and delivery. Read more about it here.
 
We've mentioned 'Ruby on Rails' quite a lot, though both CarrierWave and the Cloudinary plugin support a standard ActiveRecord model as well as a Mongoid model. In addition, some of our customers use this solution for their non-Rails frameworks, such as Sinatra.
 
For more details, see our documentation.
 
If you have additional thoughts on how we can make your life easier when managing images and attachments in your Rails applications, make sure you tell us about them. If you don't have a Cloudinary account already, you can sign up for a free account in seconds.

Recent Blog Posts

Our $2B Valuation

By
Blackstone Growth Invests in Cloudinary

When we started our journey in 2012, we were looking to improve our lives as developers by making it easier for us to handle the arduous tasks of handling images and videos in our code. That initial line of developer code has evolved into a full suite of media experience solutions driven by a mission that gradually revealed itself over the course of the past 10 years: help companies unleash the full potential of their media to create the most engaging visual experiences.

Read more
Direct-to-Consumer E-Commerce Requires Compelling Visual Experiences

When brands like you adopt a direct–to-consumer (DTC) e-commerce approach with no involvement of retailers or marketplaces, you gain direct and timely insight into evolving shopping behaviors. Accordingly, you can accommodate shoppers’ preferences by continually adjusting your product offering and interspersing the shopping journey with moments of excitement and intrigue. Opportunities abound for you to cultivate engaging customer relationships.

Read more
Automatically Translating Videos for an International Audience

No matter your business focus—public service, B2B integration, recruitment—multimedia, in particular video, is remarkably effective in communicating with the audience. Before, making video accessible to diverse viewers involved tasks galore, such as eliciting the service of production studios to manually dub, transcribe, and add subtitles. Those operations were costly and slow, especially for globally destined content.

Read more
Cloudinary Helps Minted Manage Its Image-Generation Pipeline at Scale

Shoppers return time and again to Minted’s global online community of independent artists and designers because they know they can count on unique, statement-making products of the highest quality there. Concurrently, the visual imagery on Minted.com must do justice to the designs into which the creators have poured their hearts and souls. For Minted’s VP of Engineering David Lien, “Because we are a premium brand, we need to ensure that every single one of our product images matches the selected configuration exactly. For example, if you pick an 18x24 art print on blue canvas, we will show that exact combination on the hero images in the PDF.”

Read more
Highlights on ImageCon 2021 and a Preview of ImageCon 2022

New year, same trend! Visual media will continue to play a monumental role in driving online conversions. To keep up with visual-experience trends and best practices, Cloudinary holds an annual conference called ImageCon, a one-of-a-kind event that helps attendees create the most engaging visual experiences possible.

Read more