How to make (non-stretched) square thumbnails with attachment_fu and ImageScience Mar 04

By default, if you try to make a square thumbnail from a non-square image with attachment_fu, it will stretch/squash the image to make it square instead of cropping it.

ImageScience has a method called cropped_thumbnail that will make a correct square thumbnail, but attachment_fu doesn't use it.

To fix this, change the resize_image method in vendor/plugins/attachment_fu/lib/technoweenie/attachment_fu/processors/image_science_processor.rb like this:

def resize_image(img, size)
  # create a dummy temp file to write to
  # ImageScience doesn't handle all gifs properly, so it converts them to
  # pngs for thumbnails.  It has something to do with trying to save gifs
  # with a larger palette than 256 colors, which is all the gif format
  # supports.
  filename.sub! /gif$/, 'png'
  content_type.sub!(/gif$/, 'png')
  self.temp_path = write_to_temp_file(filename)
  grab_dimensions = lambda do |img|
    self.width  = img.width  if respond_to?(:width)
    self.height = img.height if respond_to?(:height)
    img.save self.temp_path
    self.size = File.size(self.temp_path)
    callback_with_args :after_resize, img
  end

  size = size.first if size.is_a?(Array) && size.length == 1
  if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))
    if size.is_a?(Fixnum)
      img.thumbnail(size, &grab_dimensions)
    else
      if size[0] == size[1]
        img.cropped_thumbnail(size[0], &grab_dimensions)
      else
        img.resize(size[0], size[1], &grab_dimensions)
      end
    end
  else
    new_size = [img.width, img.height] / size.to_s
    img.resize(new_size[0], new_size[1], &grab_dimensions)
  end
end

Then in your model, if you specify a thumbnail (or a resize) with square dimensions, it will use cropped_thumbnail and create a proper square thumbnail:

class Photo < ActiveRecord::Base
  has_attachment :content_type => :image, 
                 :storage => :file_system, 
                 :max_size => 1.megabytes,
                 :resize_to => '320x200>',
                 :thumbnails => { :small => [20, 20], :thumb => [50, 50] },
                 :processor => 'ImageScience'

  validates_as_attachment
end

1 comment

1 comment

Mike May 09 2008

I can't believe how hard it was to find out how to do this! Thanks!

Add a comment

Name (required)
Email (won't be displayed)
URL (include http://)
Comment (required)