Saturday, April 12, 2008

 

ImageMagick and RMagick

There is now a "standard" (free, BSD-style) image manipulation library ImageMagick. As it is pretty customary these days, it provides bindings for many popular higher-level languages, including Java, .NET, PHP, Perl, Python and Ruby. Ruby binding is known as RMagick.

One problem with ImageMagick is that it is notoriously difficult to install. The root of this problem may be that library insists on integration with X-server libraries (and indeed provides some X-client capabilities, though interestingly enough not supported on Windows).

(As a result, people are coming up with various ways to make a smaller library with restricted functionality, e.g. mini-magick. Unfortunately, there seems to be no documentation available, other than this tutorial, so I didn't want to spend time researching this)

Cygwin does include ImageMagic (you'll need at least 2 cygwin packages for ImageMagic: image-magick and libMagick-devel and various dependents for some reason not picked up by cygwin setup utility, e.g. libXft-devel and libbz2-devel), but all my attempts to first install ImageMagic and then RMagic failed (perhaps bundled version was too old, though judging from version numbers it was ok). ImageMagick web site includes pre-built version of all libraries for cygwin, but it appears to be very poorly built, includes many hardcoded paths from original build machine, etc.

So, the only option was to install ImageMagick from the sources, and it succeeded, after I explicitly excluded Perl bindings

./configure --without-perl

(be aware that built could take several hours to complete). After that, RMagick can be installed with command as simple as:

gem install rmagick

To try it out, you can use this program; try to uncomment line "canvas.display" near the end and look at the result. This didn't work well under Cygwin at all (though displaying same image just read from file worked fine).

Library itself is very powerful indeed. Documentation is good and detailed. One interesting thing that I discovered is that library has no less than 3 different methods to resize an image: "to sample", "to scale", and "to resize". You can compare all three by picking some random picture (sufficiently large) and running on it program like that:

#! /usr/local/bin/ruby -w

require 'rubygems'
require 'RMagick'
include Magick

imgfile = ARGV[0]
img = (Image.read imgfile)[0]

factor = 0.25
osize = File.size imgfile
puts "Original file #{imgfile} : #{osize} bytes, factor=#{factor}"

[:sample, :resize, :scale].each { |resize_alg|
  t = Time.now
  img_resized = img.method(resize_alg).call factor
  dt = Time.now - t
  fname = "test_#{resize_alg}.jpg"
  img_resized.write( fname );
  size = File.size fname
  puts "#{sprintf("%-6s",resize_alg)}: #{dt.to_f} secs, #{size} bytes =\
 #{sprintf("%.2f",100*size.to_f/osize)}%"
}

On my machine, it generated this output:

sample: 0.012 secs, 258985 bytes= 11.08%
resize: 1.287 secs, 227424 bytes= 9.73%
scale : 0.469 secs, 222147 bytes= 9.51%

Which is mathematically interesting: apparently, "resize" and "scale" provide some smoothing, therefore reducing size of the compressed image; "sample" is by far the fastest way to resize, but by just picking some more or less random pixels from the original image it generated result which is not only visually worse, but is harder to compress.

Labels: , ,


Comments:
Hi,

Can u tell me about Image magic i want to use it to resize the image in my webapplication of java.

Thanks
Miral Amin
 
Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?