Creating Retina Images with CarrierWave

Posted on

In yesterday's post Retina Web Design, we covered multiple techniques to be "retina-ready" for the upcoming wave of double density screens. One of the techniques mentioned was to use retina.js, a JavaScript library that attempts to serve higher resolution images for visitors of your web application. To ensure even your uploaded image assets will work with retina.js, we can utilize CarrierWave to upload both standard and high resolution image versions.

One constraint we must conform to is naming our "retina" image versions to use the Apple @2x naming style. CarrierWave allows us to set a specific file name for each version of an uploaded file. To do this, we must override the #full_filename method defined in the CarrierWave::Uploader::Versions module.

Example

The key to using this technique is to not resize the original version of the image smaller than the "retina" version. In the example below, we do not process the original image and instead create a thumb and retina_thumb version. Also note that when creating a "retina" image, the dimensions must be double the size of the standard definition version.

class AvatarUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  version :thumb do
    process resize_to_fill: [100, 100]
  end

  version :retina_thumb do
    process :resize_to_fill => [200, 200]

    def full_filename(for_file = model.avatar.file)
      super.tap do |file_name|
        file_name.gsub!('.', '@2x.').gsub!('retina_', '')
      end
    end
  end
end

Processing a png image to the AvatarUploader above, would result in three versions uploaded to your asset store:

  • The original file
  • A thumbnail named thumb.png with dimensions 100x100
  • A retina thumbnail named thumb@2x.png with dimensions 200x200

APIs

This technique is also useful for APIs designed specifically for iOS applications. If an API endpoint returns images, you can return both standard and high resolution version paths of the image and leave the decision of which version to use to the API consumer.

002

This post is by Kevin Faustino. Kevin is the Chief Craftsman of Remarkable Labs and also the founder of the Toronto Ruby Brigade.


Comments

comments powered by Disqus