by mars on 2006-07-16 3 Comments
filed in Work with tags , , ,

Mogrify is ImageMagick's command-line utility to transform images. I'm using it within MiniMagick, a Rails plugin that allows image manipulation with minimum memory usage compared to the more ruby-like RMagick bindings.

So the point of this post... Do you get errors like "mogrify: unable to open module file" when it's looking for a coder?

The whole error is like:

mogrify: unable to open module file 
`/usr/local/lib/ImageMagick-6.2.8/modules-Q8/coders/1.la': 
No such file or directory.

The problem is that Ruby's Tempfile naming scheme uses a numeric filename extension, for example "tempfile666.1" instead of a more meaningful "tempfile666.jpg". Mogrify understands an image file without a filename extension, but apparently an erroneous file extension overrides that magic mechanism.

So, we need to change the behavior of the Tempfile class to avoid that problematic extension. In the ruby code, before loading images with MiniMagick, open up that Tempfile class and redefine #make_tmpname to use a hyphen instead of a period.

Before *(lifted from /usr/local/lib/ruby/1.8/tempfile.rb)*:

1
2
3
4
5
    class Tempfile
      def make_tmpname(basename, n)
        sprintf('%s%d.%d', basename, $$, n)
      end
    end

After *(when defining your MiniMagick-implementing class)*:

1
2
3
4
5
6
    # fix Tempfile to work with mogrify by removing filename extension
    class Tempfile
      def make_tmpname(basename, n)
        sprintf('%s%d-%d', basename, $$, n)
      end
    end

3 Responses to “of Mogrify, Ruby Tempfile & Dynamic Class Definitions”

mzpn commented
2007-07-15 at 10:48 AM
fun
Steve commented
2007-07-15 at 10:48 AM
I had the same exact problem and extended your idea a little. This modification to make_tmpname allows you to create temp files with whatever extension you like (but if you don't specify an extension, it works like normal):
Module MiniMagick
  class ImgTempFile < Tempfile
    def make_tmpname(basename, n)
      # force tempfile to use basename's extension if provided
      ext = File::extname(basename)
      # force hyphens instead of periods in name
      sprintf('%s%d-%d%s', File::basename(basename, ext), $$, n, ext)
    end
  end # class
end # module
Also, I chose to subclass Tempfile rather than overwrite, which required a small alteration to mini_magick.rb:
          tmp = ImgTempFile.new("minimagic")
Finally, here's a short test that shows it's working (put it in any convenient test file that gets run on related stuff):
  def test_image_temp_file
    tmp = MiniMagick::ImgTempFile.new('test')
    assert_match %r{^test}, File::basename(tmp.path)
    tmp = MiniMagick::ImgTempFile.new('test.jpg')
    assert_match %r{^test}, File::basename(tmp.path)
    assert_match %r{\.jpg$}, File::basename(tmp.path)
  end
Matt commented
2008-04-28 at 09:57 AM

Do you know if the newest version fixes this? == 1.2.2 / 2007-06-01

Leave a Reply

Markdown is in effect.



Everything is here.