5
votes

I'm working on the rails backend of a native app.

In a native app, retina (high resolution) images are automatically loaded using the @2x naming convention.

For example, you can have two images called image.png and [email protected] (the higher resolution version of the same image). If the app is running on an iPhone 3gs, image.png is automatically loaded. If the app is used on an iPhone 4, [email protected] will be loaded automatically.

This @2x convention doesn't work for non-native web apps according to what I've read and seen in action.

It seems that Apple's @2x convention doesn't work for images supplied by a Rails backend. I know that media queries can help with this, but I'm wondering if there is some sort of work around for having an iPhone 4 automatically load @2x images from a web app instead of the non-highres counterpart.

6
You're going to need to explain this so much better if you want anyone to answer it. Especially what you mean by the @2x conventionRyan Bigg
@RyanBigg The '@2x' naming convention will be instantly familiar to any iOS developer. It's simply a way of naming an alternate, high-resolution version of an image so that it will be recognized and used by high-resolution devices.Caleb

6 Answers

4
votes

I suggest the following:

In your rails app, create different versions of the images when uploaded.

Then in the iOS app, you could have a look at the scale property of UIScreen and determine which image to load:

if ([[UIScreen mainScreen] scale] == 2.0f){
  //load retina image
} else {
  //load non-retina image
}
2
votes

The HiSRC gem works nicely: https://github.com/haihappen/hisrc-rails

It uses the same naming convention as Apple (@2x for retina images) and automatically serves the correct one.

I used this in conjunction with CarrierWave, creating two thumbnail versions upon upload:

version :retina_thumb do
  process :resize_to_fill => [200, 200]
  def full_filename (for_file = model.photo.file)
    "[email protected]"
  end
end

version :thumb, :from_version => :retina_thumb do
  process :resize_to_fill => [100, 100]
  def full_filename (for_file = model.photo.file)
    "thumb.jpg"
  end
end

And in your view:

<%= responsive_image_tag user.photo_url(:thumb).to_s %>

Another gem I tried was Clear Eyes, but I couldn't get it to work...

1
votes

Is this not the simplest solution - or do I miss something?

<%= image_tag("image.png", srcset: { "[email protected]" => "2x"}) %>
0
votes

I've written a rails gem this should solve the problem

0
votes

I've packaged a solutions as a gem https://github.com/jhnvz/retina_rails

Al you have to do is:

  1. Add gem 'retina_rails' to your Gemfile.
  2. Run bundle install.
  3. Add //= require retina to your Javascript manifest file (usually found at app/assets/javascripts/application.js).

Carrierwave

  1. Add include RetinaRails::CarrierWave to the bottom of your uploader

    class ExampleUploader < CarrierWave::Uploader::Base
    
      version :small do
        process :resize_to_fill => [30, 30]
      end
    
      include RetinaRails::CarrierWave
    
    end
    

Paperclip

  1. Add include RetinaRails::Paperclip to the bottom of your uploader

    class ExampleUploader < ActiveRecord::Base
    
      has_attached_file :image,
        :styles => {
           :original => ["800x800", :jpg],
           :big => ["125x125#", :jpg]
         }
    
      include RetinaRails::Paperclip
    
    end
    

The gem automatically generates retina versions (appends @2x to filename) based on your defined versions in an uploader. The js checks if the users got a retina display and if so appends @2x to the image file name.

Also posted this answer in: How do you generate retina (iPad) friendly (progressive or interlaced) jpeg images with CarrierWave?

0
votes

What do you think about this approach:

Uploading a raw file with high resolution and then just generate the 3 different sizes. Here for an Icon model I want to implement:

  has_attached_file :attachment,
  storage: :s3,
  s3_credentials: Rails.configuration.aws,
  s3_protocol: :https,
  s3_host_name: 's3.amazonaws.com',
  url: ':s3_domain_url',
  path: ':class/:attachment/:id_partition/:style_:basename.:extension',
  styles: {
    '@3x_thumb': '192x192>',
    '@2x_thumb': '128x128>',
    'thumb': '64x64>'
  },
  convert_options: { 
    all: '-strip', 
    '@3x_thumb': '-quality 100 -interlace Plane', 
    '@2x_thumb': '-quality 100 -interlace Plane', 
    'thumb': '-quality 100 -interlace Plane'
    },
  :s3_headers => { 'Cache-Control' => 'max-age=3600' }

I am not sure what convert option are correct but the naming and sizing problem is solved.