<?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>Nick Sieger: ImageVoodoo 0.1 Released</title>
    <link>http://blog.nicksieger.com/articles/2008/03/27/imagevoodoo-0-1-released</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>"ImageVoodoo 0.1 Released" by Miami Web Design</title>
      <description>&lt;p&gt;Thanks a lot, I have been searching for an alternative to ImageScience for quite some time (don&amp;#8217;t ask :P) and this is exactly what I wanted :)&lt;/p&gt;</description>
      <pubDate>Wed, 09 Apr 2008 13:10:43 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:c1da65d0-148c-4504-887a-01196dec0fac</guid>
      <link>http://blog.nicksieger.com/articles/2008/03/27/imagevoodoo-0-1-released#comment-393</link>
    </item>
    <item>
      <title>"ImageVoodoo 0.1 Released" by Christian Seiler</title>
      <description>&lt;p&gt;Thanks so much for this. I always avoided installing those C-based image processing libraries on my development machine (Windows), because it&amp;#8217;s such a pain in the ass. Now ImageVoodoo simply works. gem install, and that&amp;#8217;s it. This is where Java really shines.&lt;/p&gt;</description>
      <pubDate>Tue, 01 Apr 2008 09:38:03 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:4a9825c3-35ba-4029-8f40-361050c20a5a</guid>
      <link>http://blog.nicksieger.com/articles/2008/03/27/imagevoodoo-0-1-released#comment-392</link>
    </item>
    <item>
      <title>"ImageVoodoo 0.1 Released" by Matthew Kanwisher</title>
      <description>&lt;p&gt;Heh I bumped into your git project looking for a way to use attachment_fu in jruby. Good to hear you have a 0.1 version ;)&lt;/p&gt;</description>
      <pubDate>Fri, 28 Mar 2008 17:09:53 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:996dcafd-d676-410c-8268-2663c3a03673</guid>
      <link>http://blog.nicksieger.com/articles/2008/03/27/imagevoodoo-0-1-released#comment-391</link>
    </item>
    <item>
      <title>ImageVoodoo 0.1 Released</title>
      <description>&lt;h2&gt;Introducing ImageVoodoo&lt;/h2&gt;

&lt;p&gt;I just pushed out the first release of ImageVoodoo, a nifty little image manipulation library conceived as a quick hack by &lt;a href="http://www.bloglines.com/blog/ThomasEEnebo" title="Tom's Ruminations - Powered By Bloglines"&gt;Tom&lt;/a&gt;. It&amp;#8217;s a play-on-words of &lt;a href="http://seattlerb.rubyforge.org/ImageScience.html" title="ImageScience"&gt;ImageScience&lt;/a&gt;, of course, the quick, lightweight imaging library for Ruby. To get it,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jruby -S gem install image_voodoo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What&amp;#8217;s cool about ImageVoodoo (other than the name) is that we were able to make it API-compatible with ImageScience. In fact, ImageVoodoo&amp;#8217;s &lt;code&gt;image_science.rb&lt;/code&gt; simply looks like this:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;image_voodoo&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="comment"&gt;# HA HA...let the pin-pricking begin&lt;/span&gt;
&lt;span class="constant"&gt;ImageScience&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;ImageVoodoo&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So, you can use it pretty much anywhere you might use ImageScience, and it should &lt;em&gt;just work&lt;/em&gt;. At work, we&amp;#8217;re using it with &lt;a href="http://github.com/technoweenie/attachment_fu/tree/master"&gt;attachment_fu&lt;/a&gt;, and it works great. ImageVoodoo even steals and uses ImageScience&amp;#8217;s unit tests (which all run successfully, too). Speed-wise, it&amp;#8217;s about twice as slow as ImageScience running on MatzRuby, but still plenty fast enough for most cases.&lt;/p&gt;

&lt;p&gt;But we wouldn&amp;#8217;t be having fun unless we embraced and extended a little bit, right? So I added a couple of extra features you might find useful.&lt;/p&gt;

&lt;h2&gt;Preview&lt;/h2&gt;

&lt;p&gt;Since ImageVoodoo is just leveraging the Java Platform&amp;#8217;s imaging libraries, image rendering can be easily tied into a simple preview frame. This code:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="constant"&gt;ImageVoodoo&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;with_image&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;samples/checkerboard.jpg&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;img&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;img&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;preview&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Will pop up a little frame like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="/files/image_voodoo_preview.png" alt="preview" title="preview"/&gt;&lt;/p&gt;

&lt;p&gt;The code that displays the preview frame is nice and compact, and shows off how nicely you can write clean swing GUI code using JRuby&amp;#8217;s java integration features.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;ImageVoodoo&lt;/span&gt;
  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;JImagePanel&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;javax&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;swing&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;JPanel&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;image&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;y&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="keyword"&gt;super&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
      &lt;span class="attribute"&gt;@image&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="attribute"&gt;@x&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="attribute"&gt;@y&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;image&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;x&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;y&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;paintComponent&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;graphics&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="ident"&gt;graphics&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;drawImage&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@image&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="attribute"&gt;@x&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="attribute"&gt;@y&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;WindowClosed&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;block&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="attribute"&gt;@block&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;block&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="ident"&gt;proc&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;java&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;lang&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;System&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;exit&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;method_missing&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;meth&lt;/span&gt;&lt;span class="punct"&gt;,*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;);&lt;/span&gt; &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;windowClosing&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;event&lt;/span&gt;&lt;span class="punct"&gt;);&lt;/span&gt; &lt;span class="attribute"&gt;@block&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;;&lt;/span&gt; &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;preview&lt;/span&gt;&lt;span class="punct"&gt;(&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;javax&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;swing&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;JFrame&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Preview&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
    &lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add_window_listener&lt;/span&gt; &lt;span class="constant"&gt;WindowClosed&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;set_bounds&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;width&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;20&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;height&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;40&lt;/span&gt;
    &lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add&lt;/span&gt; &lt;span class="constant"&gt;JImagePanel&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@src&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;visible&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Command-line&lt;/h2&gt;

&lt;p&gt;As I was &lt;a href="http://twitter.com/nicksieger/statuses/778203542"&gt;fixing a bug in ImageVoodoo&amp;#8217;s file saving&lt;/a&gt; I whipped up a little command-line utility to aid debugging. It allows you to string along several image manipulation actions on a single command-line. For example,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;jruby -S image_voodoo --push --resize 50x50 --preview --save t1.jpg \
  --pop --resize 40x40 --preview --save t2.jpg \
  --pop --resize 30x30 --preview --save t3.jpg image.jpg
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will resize &lt;code&gt;image.jpg&lt;/code&gt; into three smaller images, &lt;code&gt;t[1-3].jpg&lt;/code&gt;, but will pop up a preview frame at each step of the way. Simply close the preview frame to continue to the next action, or quit out of the application to abort.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;And so, another functional area, image manipulation, becomes as easy on JRuby as it is on MatzRuby. Now that fancy social networking application you&amp;#8217;ve been working on should have one less reason to be able to run unmodified on JRuby!&lt;/p&gt;</description>
      <pubDate>Thu, 27 Mar 2008 21:39:23 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:3b535c66-18f9-4ae5-9e37-79757d8b7a32</guid>
      <author>Nick Sieger</author>
      <link>http://blog.nicksieger.com/articles/2008/03/27/imagevoodoo-0-1-released</link>
      <category>jruby</category>
      <category>ruby</category>
      <category>image</category>
      <category>voodoo</category>
      <category>science</category>
      <trackback:ping>http://blog.nicksieger.com/articles/trackback/390</trackback:ping>
    </item>
  </channel>
</rss>
