martes, 19 de abril de 2011

Released ImageRuby - a flexible ruby gem for image processing

ImageRuby is a flexible gem for image processing, it's designed to be easy to install and use. The core of ImageRuby is written in pure ruby and the installation is as simple as execute "gem install imageruby". The API of the library take advantage of sugar syntax constructions specific of ruby language such as method chaining and blocks. e.g, the next code loads an image from "input.bmp", crop the rectangle from 0,0 to 49,49 (50x50 pixels), replace the orange color to red color, replace the black color to orange color and finally saves the image as "output.bmp"

require "imageruby"

ImageRuby::Image.from_file("input.bmp")[0..49,0..49].
color_replace(Color.orange,Color.red).
color_replace(Color.black,Color.orange).
save("output.bmp", :bmp)

Current Status

The ImageRuby had his first release (version 0.1.0) the last week with imageruby-c (extension to override a few methods with C methods) and imageruby-bmp (support for save and load images on BMP format),

You can install the gem by doing

gem install imageruby


The current version o imageruby has no dependencies, and it's installation should be as simple as that, optionally, you can install imageruby-c to improve the performance of draw and color_replace methods and imageruby-bmp to have support for bmp images.
The extensions take effect automagically by installing the gem, there is no need to do something specific in the ruby script (e.g. when install imageruby-c the methods will be optimized)

Goals of the project

  • Become synonymous of image processing in the ruby world, displacing other options in the "market" but re-using the existent stuff (giving credit, obviously)
  • Highlight deficiencies in the ruby language when used for heavy processing (e.g. draw method implemented in ruby is very slow)
  • Spike workarounds for the Ruby language issues
  • Spike "soft" dependency model or plugin gems to avoid the problems of "static" dependencies

Competitors

There is a range of gems for image processing on ruby, most of these are based on C libraries and implies the need for a compiler in order to install them. Some have "low level" bugs such memory leaks but most of them have many possibilities through their API

  • RMagick: Ruby wrapper of the archi-famous ImageMagick library. Has reported problems with low level memory handling and is not recommended for services environment (such as a Rails application) but is good for scripting
  • ImageScience: More stable alternative to RMagick, written on top of FreeImage and RubyInline (for more optimal code in C), an issue when using this library is the RubyInline dependency which implies the need for GCC installed on the system, something that is simple on Linux but is so tricky in other environments such Windows and Heroku
  • Camellia: A C/C++ library with a Ruby interface apparently directed to photo processing, there is no gem and the installation should be using the classic command sequence ./configure; make; make install.
  • Devil: Wrapper of C library of the same name. It has a wide range of operations over an image including blur and equalize. (see documentation)
  • Ruby-Processing: Well documented library mainly oriented to interactive media including video features. Has nice pencil functions
Future

New image formats

One of the next big steps will be develop decoder and encoders for common image formats, the encoders and decoders can be released as separated gems (like imageruby-bmp) without need for change imageruby core. In fact, anyone can make their own encoder or decoder.

Competitors become allies

Re-use the existing development around image processing in the ruby world, divided in two big groups: Interfaces and Implementations

Reusing interfaces implies the creation of "mocks" or "wrappers" of ImageRuby providing the same API of other library (e.g. RMagick or ImageScience) to reduce the learning curve of ImageRuby API and provide a method to replace that library with ImageScience transparently for code developed on top of that (e.g. a rails application using ImageMagick and then the ImageMagick gem is replaced by ImageRuby, app will not need to be modified)

Reusing implementation is about build features on top of other image libraries, but without setting a "hard" o "static" dependency with the library, but by creating a optional extension for ImageRuby (something like a port between libraries). Example: imageruby-devil.

Could be installed so:
gem install imageruby-devil

And used like
# is not necessary to make a explicit require of imageruby-devil
require "imageruby"

image = ImageRuby::Image.from_file("input.bmp")

image.color_replace!(Color.black, Color.purple) # use a method of ImageRuby
image.devil.blur(1) # use a method of Devil library on the image

image.save("output.bmp", :bmp)

Feedback for Ruby improvements

One of the goals of ImageRuby is to Highlight deficiencies in the ruby language , methods such draw or color_replace process hundred of thousands of pixels per image which in the ruby language implies still much more unnecessary rubymorphic calls just to access each bit of pixel data of the processed images. This produces a very very slow result, the current workaround for this issue is override the "heavy" methods with the imageruby-c extension. This was achieved as a optional extension to avoid the unnecessary hard dependency of have a compiler in the system, ImageRuby without imageruby-c installed HAS the draw and color_replace method, but with the imageruby-c gem installed, is much much more fast (near to 100x more faster)

Links

ImageRuby rdoc reference: http://tario.github.com/imageruby/doc/
ImageRuby GitHub site: https://github.com/tario/imageruby

2 comentarios:

  1. Hello,
    thanks for posting and sharing imageruby.

    I am about to use it with today's ruby 1.8 interpreter, however your GEM seems to have some coding problems : using deprecated methods, plus error making it unable to save any image (gosh)

    could you please fix it ? or give a clue how to fix it...

    here are the logs:
    being in /var/lib/gems/1.8/gems/imageruby-0.2.1/examples
    $ ruby gradient.rb

    NOTE: Gem.source_index is deprecated, use Specification. It will be removed on or after 2011-11-01.
    Gem.source_index called from /var/lib/gems/1.8/gems/imageruby-0.2.1/lib/imageruby/abstract/auto_require.rb:24.
    NOTE: Gem::SourceIndex#each is deprecated with no replacement. It will be removed on or after 2011-11-01.
    Gem::SourceIndex#each called from /var/lib/gems/1.8/gems/imageruby-0.2.1/lib/imageruby/abstract/auto_require.rb:24.
    /var/lib/gems/1.8/gems/imageruby-0.2.1/lib/imageruby/filepersistor.rb:41:in `persist': ImageRuby::FilePersistor::UnableToPersistException (ImageRuby::FilePersistor::UnableToPersistException)
    from /var/lib/gems/1.8/gems/imageruby-0.2.1/lib/imageruby/pureruby.rb:34:in `save'

    regards,
    Seb.

    ResponderEliminar
    Respuestas
    1. The ideal place to leave issues about the project is the github page of the gem: https://github.com/tario/imageruby

      Remember that in order to get the examples work you must install additional gems (I will work in order to make it easier to figure out), examples make use of loading a saving images in bmp format, so you must install imageruby-bmp. Te reason for this is that imageruby gem is being designed in order to avoid static/explicit dependencies (avoid the problem "I can´t use X gem because depends on gem Y which does not work on my system", for example, you actually can install imageruby-bmp-c instead of imageruby-bmp for better performance and imageruby-devil is also available for much more formats/effects/etc..., but installing this gems IS NOT MANDATORY, these only adds more features

      Currently, I have no environment and therefore I can not test the problem, but I think that you need to install the missing gem (imageruby-bmp or imageruby-bmp-c, visit the github page/see README for more info)

      I coded the gem to be compatible both with ruby1.9 and ruby1.8, but (like the ruby core team) I strongly recommend migrating to ruby1.9

      Of course, any recommendations, bug reports like this, criticism, patches, etc... are very welcome

      regards,
      Dario

      Eliminar