MojoMagick: Ruby Image Library (for ImageMagick) 22

Posted by science on January 30, 2008

Magick!

Science releases MojoMagick, a Ruby language image library “that does very little” ™. There are several useful image tools that “do a lot” – MojoMagick is designed to just a few things:

  • Be fast
  • Don’t leak memory
  • Make simple ImageMagick tasks, simple as Ruby tasks
  • Permit direct access to ImageMagick for complex tasks (i.e. get out of your way)
  • Provide a central access to ImageMagick for good code architecture
  • Easy to extend
  • Limit memory accessible to ImageMagick (where desired)

That’s what it does. It’s packaged as a Rails plugin, but does not require Rails to run. You can also install it as a gem.

You can download a copy by following the instructions here.

2013 Update: Rcode5 has posted a github version which should probably be considered canonical for now: https://github.com/rcode5/mojo_magick

Trackbacks

Use this link to trackback from your own site.

Comments

Leave a response

  1. weepy Tue, 12 Feb 2008 00:21:12 UTC

    Looks very interesting. How does it differ from Rmagick/minimagick ?

    A gem would be a very good idea

  2. science Tue, 12 Feb 2008 10:43:24 UTC

    RMagick hooks ImageMagick via DLL’s (last I looked). As a result it leaks memory like a sieve (last I looked). It’s fine for Ruby processes where the interpreter spins up, runs your code, and exits back to the OS. But it’s pretty bad in Rails, where the the interpreter spins up, and is re-entrant into the Rails stack over and over.

    Minimagick is very similar to MojoMagick in that they both use shell execution to accomplish their work. As a result, they don’t leak memory like RMagick. However, I have personal, anecdotal experience with Minimagick also leaking memory. I can’t say for sure, but that’s my unscientific experience.

    Most importantly, MiniMagick uses temp files to manipulate images. So if you want to get the size of an image in MiniMagick, the framework will copy your image to a temp file, and get the size of the temp file. If you want to resize an image in place, it will copy to a temp file, resize and copy back to the original. MojoMagick permits you to operate on a file directly and its built in functions (like resize and “get dimensions”) do this automatically for you.

    Significantly, MojoMagick supports easily limiting memory usage in ImageMagick. IM can use a surprising amount of memory and if you are in a limited RAM environment it can cause your core application to swap to disk which is Not Good.

    To limit memory usage in MojoMagick, be sure you’re upgraded to the current release of ImageMagick. Then you can use this code to examine and limit various ram components:

      # obtain/print a hash of current/default limits
      puts MojoMagick::get_default_limits.inspect
    
      # set/print limits on disk, area, map and ram usage
      MojoMagick::set_limits(:area => '32mb', :disk => '0', :memory => '64mb', :map => '32mb')
      puts MojoMagick::get_current_limits.inspect

    I’ll get to work on a gem soon!

  3. science Tue, 19 Feb 2008 11:09:23 UTC

    Version 0.0.2 released: improved resource limits, error trapping

  4. al Fri, 29 Feb 2008 12:27:39 UTC

    This is fantastic… saves me the hassle of hacking up minimagick to convince it to pass a command line.

  5. Will Mon, 30 Jun 2008 08:34:27 UTC

    A gem would be fantastic!

  6. science Mon, 30 Jun 2008 15:27:42 UTC

    Ok – Science may be lazy but does get the point. Gem created!

    MojoMagick version 0.2.0 GEM

    To install, save the above file to a temp folder. The run from that folder:

    gem install mojo_magick
    

    Remember that only works when you run the command from the folder where you d/l'ed the gem file!

    You can always browse for the latest Gem version here: http://trac.misuse.org/science/browser/mojo_magick/trunk/pkg I'll try to update the Gem every time I time I push new code.

  7. weepy Mon, 30 Jun 2008 23:31:48 UTC

    awesome – nice work !

    Is there an obvious way to map an IM command to Mojo ?

  8. science Mon, 30 Jun 2008 23:32:41 UTC

    Yup that’s an important “feature” of Mojo – if you look in the “lib” folder you can see how I do it for the “resize” command for example:

    retval = MojoMagick::raw_command("convert", "\"#{source_file}\" -resize #{options[:width]}X#{options[:height]}#{scale_options} \"#{dest_file}\"")
    

    So basically you pass two params to “raw command”:

    #1 the actual IM command you wish to run as a string

    #2 the parameters (all in one string).

    At this point, it’s important that you pass the command separate from the parameters only if you are using the feature that lets you limit the amount of memory IM is going to use.. (that has to be put on the IM command line after the command but before the args).

  9. Al Thu, 24 Jul 2008 17:35:56 UTC

    You may want to put a simple sample script that has defaults so that new users can learn to make ruby do resizing with your gem; ex: resize all images in a folder to a certain size

    Just my 2 cents that would really be useful

    Thanks

  10. science Tue, 29 Jul 2008 10:05:49 UTC

    Al: You got it. Here’s the code that does the job. Pretty simple, even including error handling! Make sure you’ve got MojoMagick installed someplace where Ruby can find it!

    require 'mojo_magick'
    
    image_folder = '/tmp/img'
    Dir::glob(File::join(image_folder, '*.jpg')).each do |image|
      begin
        # shrink all the images *in place* to no bigger than 60pix x 60pix
        MojoMagick::shrink(image, image, {:width => 60, :height => 60})
        puts "Shrunk: #{image}"
      rescue MojoMagick::MojoFailed => e
        STDERR.puts "Unable to shrink image '#{image}' - probably an invalid image\n#{e.message}"
      rescue MojoMagick::MojoMagickException => e
        STDERR.puts "Unknown exception on image '#{image}'\n#{e.message}"
      end
    end
    
  11. Al Tue, 09 Sep 2008 11:18:44 UTC

    Hi

    Sorry for the late response, I just saw this email and feel bad that you did not get a response. I think the code is great. I did find one bug in it that JPG and jpg are not treated the same so users may get confused since it is case sensitive.

    I really like your gem it is very easy to use.

    Hope all is well.

    Al

  12. science Tue, 09 Sep 2008 16:00:23 UTC

    Al: Good point – if you want to iterate through multiple files with variable caps casing, it can get complicated with glob – if you assume only caps and lower case, it’s simpler – try this:

    Dir::glob(File::join(image_folder, '*.{jpg,JPG}')).each do |image|
    

    That will match either case. Unfortunately glob isn’t regex so you can’t just seach case insensitive. Personally, I use the following constants to find image files (I put the second constant in the glob statement per the example above):

    IMAGE_FILE_EXT = [".jpg", ".jpeg", ".gif", ".png", ".JPG", ".JPEG", ".GIF", ".PNG"]
    IMAGE_FILE_EXT_LIST = IMAGE_FILE_EXT.join(",")
    
  13. Casen Sat, 10 Jan 2009 14:13:53 UTC

    I cannot see how to make the raw command work properly. It always puts the generated file in the application root. I am getting the image from a URL though, so not a local file. Any answers to this?

  14. science Mon, 12 Jan 2009 14:27:11 UTC

    Casen: Make sure you can make it work with ImageMagick on the command line first. For example what is the command you are trying to run in ImageMagick? From there it should be relatively easy to get the “raw_command” version for you.

    You can see how I do that by looking in “./lib/mojo_magick.rb” around line 60 — the “resize” method. You’ll see I pass the “convert” command, followed by a compound string that includes: [source file] [prog options] [dest file]

    Post again if you are stuck. -S

  15. Elliot Mon, 02 Mar 2009 14:52:59 UTC

    I’ve been using your library and I like the thin interface to ImageMagick, although I’ve rolled some of MiniMagick’s tempfile code into my copy to make some common tasks easier.

    Have you considered extending your library with some MiniMagick-like utilities? Or, alternately, are you accepting any proposed changes?

    Thanks for the plugin!

  16. science Wed, 11 Mar 2009 23:38:06 UTC

    Elliot: per our email conversations, your code additions are now checked in. Thanks for contributing and for writing tests that work!

  17. Manuel Tue, 22 Dec 2009 12:45:23 UTC

    Hi
    I am totally new to Ruby and programming in general although I have some knowledge of ActionScript and AppleScript.

    I need to automatize the conversion of a bunch of daily created “.eps” (Illustrator) files to “.jpg” and at the same time output those “.jpg” files in two sizes.

    I cloud update Ruby (I use OS X), install ImageMagick and all the dependencies without problems.
    With RMagic I could convert the .eps’s to .jpg but the background turn black on every image. So looking for alternatives I found mojomagick but I have no clue at all of how to use it :-( is there a tutorial or something for “idiots” outthere? I hadn’t been able to find any.
    Any help would be appreciated.

    Thanks in advance

  18. science Fri, 08 Jan 2010 10:29:49 UTC

    Manuel – I’m not sure if ImageMagick supports EPS files – assuming it does, Mojomagick is designed to stub the functionality of ImageMagick in an quick/dirty way. There are some tutorial examples in the wiki and inside the GEM.

  19. tom Fri, 22 Aug 2014 10:41:53 UTC

    theories@harlan.twenties” rel=”nofollow”>.…

    спс….

  20. kent Fri, 22 Aug 2014 12:32:32 UTC

    bunched@unending.unsaturated” rel=”nofollow”>.…

    tnx for info!!…

  21. Tim Sat, 23 Aug 2014 16:21:07 UTC

    chugging@shakily.corneilus” rel=”nofollow”>.…

    благодарю!…

  22. Evan Sun, 24 Aug 2014 02:40:31 UTC

    inc@ballots.means” rel=”nofollow”>.…

    good info!!…

Comments