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”
end

require ‘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
  end
end

To use it, do something like this:

begin
  iinfo = ImageInfo.new(filepath)
  my_image_width = iinfo.width
  my_image_height = iinfo.height
rescue Exception=>e
  # check errors
end

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'
    /usr/local/lib/ruby/gems/1.8/gems/image_science-1.1.3/lib/image_science.rb:84

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).

Blog Archives

Navigation


About this blog

A blog about Ruby, Rails and other tech. Mostly.


Find Something?