How to find image sizes in rails without image science

We have a nice new server which runs 64 bit fedora linux. It’s quick and good. But alas FreeImage won’t compile on this architecture. So bang goes any chance of using Image science.But really I am only interested in finding the dimensions of my images. And it shouldn’t be hard. I found this post about using the gd library to resize images. Well I don’t need to resize images, but I thought it was a good approach, so I hacked it to do what I wanted.Here is my code (credit to Damien Tanner for the original code). Very short and simple, and you just need the gd library installed together with the header files. On my system ‘yum install gd-devel’ did the trick.

if !ENV['HOME']  ENV['INLINEDIR'] = RAILS_ROOT + "/tmp"endrequire 'inline'class ImageInfo  SUPPORTED_FORMATS = %w(jpg jpeg png gif)  def initialize(filename, type=nil)    @filename = filename    @type = SUPPORTED_FORMATS.index(type || @filename[/[^.]*$/].downcase)  end  def height    unless @height      image_size    end    @height  end  def width    unless @width      image_size    end    @width  end  def fetch_image_size(filename, image_type); end  def image_size    if @type      fetch_image_size(@filename, @type)    else      raise "Unknown type of image"    end  end  inline do |builder|    builder.include '"gd.h"'    builder.add_link_flags "-lgd"    builder.c <<-"END"    void fetch_image_size(char *filename, int image_type) {      gdImagePtr im_in;      FILE *in;      in = fopen(filename, "rb");      /* Support diff image types: jpg jpeg png gif */      switch(image_type) {        case 0:        case 1: im_in = gdImageCreateFromJpeg(in);            break;        case 2: im_in = gdImageCreateFromPng(in);            break;        case 3: im_in = gdImageCreateFromGif(in);            break;      }      fclose(in);      if (im_in) {        rb_iv_set(self, "@width", INT2FIX(im_in->sx));        rb_iv_set(self, "@height", INT2FIX(im_in->sy));      }    }    END  endend

To use it, do something like this:

begin  iinfo =  my_image_width = iinfo.width  my_image_height = iinfo.heightrescue Exception=>e  # check errorsend

Image science breakage – SystemExit

Image Science is a small plugin that does just the stuff you need from RMagick, without all the weight that RMagick brings with it. It uses FreeImage to do the manipulations. (By the way, the MacPorts installation of that completely failed on my Leopard Mac, I advise you compile it by hand.)I was getting these kind of errors from my dev site:

SystemExit (exit):
/usr/local/lib/ruby/gems/1.8/gems/RubyInline-3.6.5/lib/inline.rb:70:in `exit'
/usr/local/lib/ruby/gems/1.8/gems/RubyInline-3.6.5/lib/inline.rb:70:in `rootdir'
/usr/local/lib/ruby/gems/1.8/gems/RubyInline-3.6.5/lib/inline.rb:84:in `directory'
/usr/local/lib/ruby/gems/1.8/gems/RubyInline-3.6.5/lib/inline.rb:258:in `so_name'
/usr/local/lib/ruby/gems/1.8/gems/RubyInline-3.6.5/lib/inline.rb:294:in `load_cache'
/usr/local/lib/ruby/gems/1.8/gems/RubyInline-3.6.5/lib/inline.rb:678:in `inline'

Not nice. Curiously everything worked fine on the production system. A bit of digging in the code was required. Image Science uses a gem called RubyInline to allow it to compile and install C extensions to Ruby on the fly. And RubyInline places these extensions in a directory called “.ruby_inline”. It chooses this directory from either the environment setting INLINEDIR, or if that isn’t set then HOME.And there is the problem – my dev system was running as apache which does not have a home directory.I added this kind of code:

if RAILS_ENV == "development"?? ENV['INLINEDIR'] = RAILS_ROOT + "/tmp"end

And I made sure that tmp in my rails dir was writeable by apache (but do not make it world writable, that won’t work either).