How do you generate retina (iPad) friendly (progre

2019-03-30 08:27发布

问题:

There are numerous reports that Mobile Safari downsamples very large JPEG images, making it difficult to put out retina-friendly resolutions for the new iPad.

The solution seems to be encoding JPEGs as progressive/interlaced files. Hence, I'm curious how I might use the CarrierWave plugin, and RMagick by extension, to generate this type of file.

Thanks!

回答1:

You can use MiniMagick:

manipulate! do |img|
  img.strip
  img.combine_options do |c|
    c.quality "90"
    c.depth "8"
    c.interlace "plane"
  end
  img
end


回答2:

As of today, you will need the repository version of carriewave as options[:write] support is not yet released.

So in your Gemfile, use the following:

gem 'carrierwave', :github => "jnicklas/carrierwave"

Then, in your uploader you can define something like follow:

version :big do
  process :resize_to_limit => [1024, 1024]
  process :optimize
end

def optimize
  manipulate! do |img, index, options|
    options[:write] = {
      :quality => 90, # Change the quality to 90%
      :depth => 8, # Set the depth to 8 bits
      :interlace => "Magick::PlaneInterlace" # Add progressive support for JPEG
    }
    img.strip! # Remove profile data
  end
end

Useful reference : http://www.imagemagick.org/RMagick/doc/constants.html#InterlaceType

Enjoy!



回答3:

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.



回答4:

I could encode images to Progressive JPEG doing the following thing to my CarrierWave Uploader:

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

  process :optimize #For the real image

  version :version_1 do
    # other processes
    process :optimize
  end

  version :version_2, from_version: :version_1 do
    # other processes
    process :optimize
  end

  version :version_3, from_version: :version_2 do
    # other processes
    process :optimize
  end

  def optimize
    manipulate! do |img|
      img.combine_options do |c|
        c.strip
        c.quality '100'
        c.depth '8'
        c.interlace 'Line'
      end
      img
    end
  end

end

You have to put last the process that converts the image to Progressive JPEG otherwise it won't be converted.

Then if you already have uploaded some images and you want to "re-create" them. Imagine that your model is:

class Picture < ActiveRecord::Base
  mount_uploader :image, ImageUploader
end

So you have to do the following to recreate the versions:

Picture.order("id ASC").each do |p|
  p.image.recreate_versions! 
  puts "#{p.id}, #{p.image.url}"
end

I ordered the picture based on the ID because if it fails in the middle of the process I have the ID and I can continue from that ID. Another thing you can do is to rescue any exception, and save in an array the pictures that fails, something like this:

errored = []
Picture.order("id ASC").each do |p|
  begin
    p.image.recreate_versions! 
  rescue => e
    errored << p.id
  end
  puts "#{p.id}, #{p.image.url}"
end

Finally, to check that the image was converted to Progressive JPEG, having ImageMagick installed, type the following in the terminal:

identify -verbose PATH_TO_IMAGE | grep Interlace

If the image is Progressive JPEG, the output will be Interlace: JPEG, if not Interlace: None