How to find image sizes in rails without image science
Categories rails, ruby | 26 December, 2007 | By Stephen Sykes
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
RSS
Wow I have never realized you can use C code inside Ruby!
I wonder, what about the performance of ImageInfo? Does it needs to get compiled every time a new instance is created, or it is compiled once and then can be used without performance decrease for compilation?
Mike – rubyinline is smart – it compiles once and caches the compiled code. It usually does this into a directory called .ruby_inline in your home, although it’s configurable (look at the ENV['INLINEDIR'] setting at the top of this code).
I have had good results with performance by using inline C code – maybe 10 times faster that the same ruby. But the above example was not done for performance – I used gd for compatibility with my architecture (better than image science) and in order not to have to use a large package like RMagick for such a small task.
Superb!
[...] do not reside on our rails application server. I have previously written about how to use the GD library to find image sizes, but this requires fetching the whole file and having it available in the local file [...]
This is absolutely great! Thanks!!