<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Mad Marmot: Tag FreeImage</title>
    <link>http://www.lukeludwig.com/blog/articles/tag/freeimage</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>A blog about programming, ruby, rails, and my crazy outdoor pursuits</description>
    <item>
      <title>RMagick has memory problems. MiniMagick with Attachment_Fu is slowwww. Go ImageScience.</title>
      <description>&lt;p&gt;Most Rails applications have to deal with resizing uploaded images for the creation of thumbnails.&amp;nbsp; The main choices include &lt;a href="http://rmagick.rubyforge.org/"&gt;RMagick&lt;/a&gt;, &lt;a href="https://rubyforge.org/projects/mini-magick/"&gt;MiniMagick&lt;/a&gt;, or &lt;a href="http://seattlerb.rubyforge.org/ImageScience.html"&gt;ImageScience&lt;/a&gt;, all of which come packaged as gems. Alternatively you can write your own which really isn&amp;#39;t that difficult.&amp;nbsp; So which one should you use? First I would recommend not writing your own, because it is really nice to take advantage of one of the very fine attachment plugins that are available. &lt;a href="http://wiki.rubyonrails.org/rails/pages/File+Column+Plugin"&gt;File column&lt;/a&gt; is the old standby rails attachment plugin, but it uses RMagick. &lt;a href="http://svn.techno-weenie.net/projects/plugins/attachment_fu/"&gt;Attachment_Fu&lt;/a&gt; is more flexible since you have the choice of using RMagick, MiniMagick, or ImageScience and can switch between them easily. At &lt;a href="http://www.teamsporttech.com"&gt;TeamSportTech&lt;/a&gt; where I work I recently transitioned our relatively large rails application from using file column and RMagick to using attachment_fu and ImageScience. Originally I was planning on using MiniMagick instead of ImageScience, but it turns out that MiniMagick is quite slow. The following timing results are on my Mac Book when running in development mode, and include uploading a single 3.4 MB jpeg which is resized down to 4 different sizes. MiniMagick consistently took 18 seconds to accomplish this, RMagick 7 seconds, and ImageScience 6 seconds. This doesn&amp;#39;t accurately represent a production environment, but I do believe it is a fair comparison. Note that the time to upload is not a factor since this was done entirely on my local computer.&lt;br /&gt;&lt;br /&gt;So why is MiniMagick with attachment_fu so slow? And why not use RMagick?&amp;nbsp; RMagick and MiniMagick use the well known &lt;a href="http://imagemagick.org/"&gt;ImageMagick&lt;/a&gt; C libraries. RMagick works by providing API ruby bindings to the ImageMagick libraries, which means that RMagick operates within the ruby process. It is well documented that RMagick consumes a lot of memory and has memory leaks as well. See &lt;a href="http://blog.craigambrose.com/past/2007/11/27/image_management_that_will_scale/"&gt;Craig Ambrose&amp;#39;s article&lt;/a&gt; and a &lt;a href="http://mephistoblog.com/2007/1/9/new-asset-thumbnailing-options-available"&gt;Mephisto article.&lt;/a&gt; It appears like &lt;a href="http://rmagick.rubyforge.org/rmagick2.html"&gt;RMagick2&lt;/a&gt; provides better memory management. &lt;/p&gt;

Even if you have memory to spare, the more memory your Mongrels utilize the more garbage collection that will have to be done, which eventually will bog down the Mongrels. MiniMagick solves this memory problem by utilizing the shell commands provided by ImageMagick, which means all image manipulations are done in separate processes outside the ruby process&amp;#39; memory space. ImageScience is a different beast altogether since it uses the &lt;a href="http://sourceforge.net/projects/freeimage"&gt;FreeImage&lt;/a&gt; library instead of ImageMagick, and it is more similar to RMagick in that it runs inside the ruby process. MiniMagick has extra overhead to start up a separate process for each ImageMagick command it executes. It also has extra disk overhead since it must operate on images on the filesystem instead of images loaded in memory.&lt;br /&gt;&lt;br /&gt;I put a print out in the MiniMagick source to track all the ImageMagick commands that MiniMagick runs to accomplish this single upload with 4 resizing operations. Here is the output with timing in the order that they were executed:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;1.421884 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-0&amp;quot; &lt;br /&gt;&amp;nbsp;0.594993 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%w\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-0&amp;quot; &lt;br /&gt;&amp;nbsp;0.592467 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%h\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-0&amp;quot; &lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp;0.602928 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-1&amp;quot; &lt;br /&gt;&amp;nbsp;0.594078 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%w\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-1&amp;quot; &lt;br /&gt;&amp;nbsp;0.584066 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%h\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-1&amp;quot; &lt;br /&gt;&amp;nbsp;1.444892 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mogrify -resize &amp;quot;240x240&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-1&amp;quot; &lt;br /&gt;&amp;nbsp;0.024799 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%w\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-1&amp;quot; &lt;br /&gt;&amp;nbsp;0.019388 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%h\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-1&amp;quot; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;0.593593 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-2&amp;quot; &lt;br /&gt;&amp;nbsp;0.580201 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%w\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-2&amp;quot; &lt;br /&gt;&amp;nbsp;0.572714 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%h\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-2&amp;quot; &lt;br /&gt;&amp;nbsp;0.590181 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%h\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-2&amp;quot; &lt;br /&gt;&amp;nbsp;0.600532 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%w\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-2&amp;quot; &lt;br /&gt;&amp;nbsp;1.396459 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mogrify -shave &amp;quot;648x0&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-2&amp;quot; &lt;br /&gt;&amp;nbsp;0.973819 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mogrify -resize &amp;quot;75x75!&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-2&amp;quot; &lt;br /&gt;&amp;nbsp;0.016706 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%w\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-2&amp;quot; &lt;br /&gt;&amp;nbsp;0.016919 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%h\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-2&amp;quot; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;0.594606 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-3&amp;quot; &lt;br /&gt;&amp;nbsp;0.690731 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%w\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-3&amp;quot; &lt;br /&gt;&amp;nbsp;0.592638 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%h\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-3&amp;quot; &lt;br /&gt;&amp;nbsp;1.513243 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mogrify -resize &amp;quot;550x550&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-3&amp;quot; &lt;br /&gt;&amp;nbsp;0.028199 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%w\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-3&amp;quot; &lt;br /&gt;&amp;nbsp;0.029103 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%h\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-3&amp;quot; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;0.610143 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-0&amp;quot; &lt;br /&gt;&amp;nbsp;0.593422 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%w\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-0&amp;quot; &lt;br /&gt;&amp;nbsp;0.638836 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%h\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-0&amp;quot; &lt;br /&gt;&amp;nbsp;1.777569 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mogrify -resize &amp;quot;1024x1024&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-0&amp;quot; &lt;br /&gt;&amp;nbsp;0.089828 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%w\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-0&amp;quot; &lt;br /&gt;&amp;nbsp;0.057866 seconds:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; identify -format &amp;quot;%h\\n&amp;quot; &amp;quot;/var/folders/UE/UE7FB01vFkmqEPkTei2ABk+++TI/-Tmp-/minimagick15344-0&amp;quot;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&lt;br /&gt;So as you can see, MiniMagick executed 30 separate shell commands. You can also see the temporary files on disk that it had to create to do these operations. To be fair, it is more correct to say that Attachment Fu executed 30 MiniMagick commands. I was curious why so many identify commands were needed. Each of the identify -format commands returns either the width (%w) or height (%h) of the image, which Attachment Fu stores in the database. This is very wasteful, because the initial identify command done for each resizing operation does include the width and height in the output, which should be parsed to save time. And for some reason notice that there are 10 identify commands to retrieve the width and 10 for the height, even though there are only 5 images involved (the original and 4 resized images). I don&amp;#39;t know why this would be necessary and haven&amp;#39;t checked the source to find out. Instead of pursuing these weird findings of how Attachment Fu uses MiniMagick, I decided to switch to Image Science. It is fast and is not a hog on memory.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp; </description>
      <pubDate>Sat, 16 Feb 2008 18:35:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:4508a339-f655-467d-aef3-f8f46bb58571</guid>
      <author>Luke Ludwig</author>
      <link>http://www.lukeludwig.com/blog/articles/2008/02/16/rmagick-has-memory-problems-minimagick-with-attachment_fu-is-slowwww-go-imagescience</link>
      <category>Programming</category>
      <category>MiniMagick</category>
      <category>attachment_fu</category>
      <category>file column</category>
      <category>RMagick</category>
      <category>ImageScience</category>
      <category>ImageMagick</category>
      <category>FreeImage</category>
      <category>ruby</category>
      <category>rails</category>
      <trackback:ping>http://www.lukeludwig.com/blog/articles/trackback/7</trackback:ping>
    </item>
  </channel>
</rss>
