<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: rmagick code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sun, 27 Jul 2008 02:26:50 GMT</pubDate>
    <description>DZone Snippets: rmagick code</description>
    <item>
      <title>Generate a graph using Gruff</title>
      <link>http://snippets.dzone.com/posts/show/5168</link>
      <description>This Ruby code produced a graph using gruff.  The output shows a &lt;a href="http://twitxr.com/image/6822/"&gt;line graph&lt;/a&gt; [twitxr.com] for the different fruits. Source code origin: &lt;a href="http://nubyonrails.com/pages/gruff"&gt;Gruff Update With Bar Graphs | Ruby on Rails for Newbies&lt;/a&gt; [rubyonrails.com]&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;require 'gruff'&lt;br /&gt;&lt;br /&gt;g = Gruff::Line.new&lt;br /&gt;g.title = "My Graph" &lt;br /&gt;&lt;br /&gt;g.data("Apples", [1, 2, 3, 4, 4, 3])&lt;br /&gt;g.data("Oranges", [4, 8, 7, 9, 8, 9])&lt;br /&gt;g.data("Watermelon", [2, 3, 1, 5, 6, 8])&lt;br /&gt;g.data("Peaches", [9, 9, 10, 8, 7, 9])&lt;br /&gt;&lt;br /&gt;g.labels = {0 =&gt; '2003', 2 =&gt; '2004', 4 =&gt; '2005'}&lt;br /&gt;&lt;br /&gt;g.write('my_fruity_graph.png')&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Note: I executed the code within an irb session on my Gentoo box. With Gentoo, &lt;a href="http://gentoo-portage.com/dev-ruby/gruff"&gt;Gruff was installed&lt;/a&gt; [gentoo-portage.com] using the command emerge -va gruff. I tried installing it on Ubuntu but ran into some difficulty, even with help from the article &lt;a href="http://snippets.dzone.com/posts/show/4140"&gt;install rmagick ubuntu&lt;/a&gt; [dzone.com].&lt;br /&gt;&lt;br /&gt;*udpate 21:48 24-Feb*&lt;br /&gt;&lt;br /&gt;The following code does exactly as the same code above, however it uses XML to separate the data from the process, making it easier and more efficient to build graphs.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/usr/bin/ruby&lt;br /&gt;# file: xml2gruff.rb&lt;br /&gt;&lt;br /&gt;require 'rexml/document'&lt;br /&gt;require 'gruff'&lt;br /&gt;include REXML&lt;br /&gt;&lt;br /&gt;class Xml2Gruff&lt;br /&gt;  &lt;br /&gt;  def initialize(filename)&lt;br /&gt;    file = File.new(filename, 'r')&lt;br /&gt;    doc = Document.new(file)&lt;br /&gt;    # get the title&lt;br /&gt;    @title = doc.root.elements['summary/title'].text&lt;br /&gt;    &lt;br /&gt;    @record = Hash.new&lt;br /&gt;    # get each record&lt;br /&gt;    doc.root.elements.each('records/item') {|item|&lt;br /&gt;      avalues = Array.new&lt;br /&gt;      item.elements.each('values/value') { |value| avalues &lt;&lt; value.text.to_i }&lt;br /&gt;      @record[item.elements['label'].text] = avalues&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    # get the summary labels&lt;br /&gt;    @labels = Hash.new  &lt;br /&gt;    doc.root.elements.each('summary/scale/label') {|l| @labels[l.elements['value'].text.to_i] = l.elements['title'].text} &lt;br /&gt;    &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def save_line_graph(filename)&lt;br /&gt;&lt;br /&gt;    g = Gruff::Line.new&lt;br /&gt;    g.title = @title &lt;br /&gt;    @record.each {|label, data| g.data(label, data) }&lt;br /&gt;    g.labels = @labels&lt;br /&gt;    g.write(filename)&lt;br /&gt;&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;if __FILE__ == $0&lt;br /&gt; x2g = Xml2Gruff.new('my_fruit.xml')&lt;br /&gt; x2g.save_line_graph('my_fruit2.png')&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;file: my_fruit.xml&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;graph&gt;&lt;br /&gt;  &lt;summary&gt;&lt;br /&gt;    &lt;title&gt;My Graph&lt;/title&gt;&lt;br /&gt;    &lt;scale&gt;&lt;br /&gt;      &lt;label&gt;&lt;title&gt;2003&lt;/title&gt;&lt;value&gt;0&lt;/value&gt;&lt;/label&gt;&lt;br /&gt;      &lt;label&gt;&lt;title&gt;2004&lt;/title&gt;&lt;value&gt;2&lt;/value&gt;&lt;/label&gt;&lt;br /&gt;      &lt;label&gt;&lt;title&gt;2005&lt;/title&gt;&lt;value&gt;4&lt;/value&gt;&lt;/label&gt;&lt;br /&gt;    &lt;/scale&gt;&lt;br /&gt;  &lt;/summary&gt;&lt;br /&gt;  &lt;records&gt;&lt;br /&gt;    &lt;item&gt;&lt;br /&gt;      &lt;label&gt;Apples&lt;/label&gt;&lt;br /&gt;      &lt;values&gt;&lt;value&gt;1&lt;/value&gt;&lt;value&gt;2&lt;/value&gt;&lt;value&gt;3&lt;/value&gt;&lt;value&gt;4&lt;/value&gt;&lt;value&gt;4&lt;/value&gt;&lt;value&gt;3&lt;/value&gt;&lt;/values&gt;&lt;br /&gt;    &lt;/item&gt;&lt;br /&gt;    &lt;item&gt;&lt;br /&gt;      &lt;label&gt;Oranges&lt;/label&gt;&lt;br /&gt;      &lt;values&gt;&lt;value&gt;4&lt;/value&gt;&lt;value&gt;8&lt;/value&gt;&lt;value&gt;7&lt;/value&gt;&lt;value&gt;9&lt;/value&gt;&lt;value&gt;8&lt;/value&gt;&lt;value&gt;9&lt;/value&gt;&lt;/values&gt;&lt;br /&gt;    &lt;/item&gt;&lt;br /&gt;    &lt;item&gt;&lt;br /&gt;      &lt;label&gt;Watermelon&lt;/label&gt;&lt;br /&gt;      &lt;values&gt;&lt;value&gt;2&lt;/value&gt;&lt;value&gt;3&lt;/value&gt;&lt;value&gt;1&lt;/value&gt;&lt;value&gt;5&lt;/value&gt;&lt;value&gt;6&lt;/value&gt;&lt;value&gt;8&lt;/value&gt;&lt;/values&gt;&lt;br /&gt;    &lt;/item&gt;&lt;br /&gt;    &lt;item&gt;&lt;br /&gt;      &lt;label&gt;Peaches&lt;/label&gt;&lt;br /&gt;      &lt;values&gt;&lt;value&gt;9&lt;/value&gt;&lt;value&gt;9&lt;/value&gt;&lt;value&gt;10&lt;/value&gt;&lt;value&gt;8&lt;/value&gt;&lt;value&gt;7&lt;/value&gt;&lt;value&gt;9&lt;/value&gt;&lt;/values&gt;&lt;br /&gt;    &lt;/item&gt;&lt;br /&gt;  &lt;/records&gt;&lt;br /&gt;&lt;/graph&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Reference: &lt;a href="http://gruff.rubyforge.org/"&gt;gruff's gruff-0.2.9 Documentation&lt;/a&gt; [rubyforge.org]&lt;br /&gt;&lt;a href="http://www.google.com/url?sa=t&amp;ct=res&amp;cd=4&amp;url=http%3A%2F%2Ftopfunky.com%2Fclients%2Fblog%2F2006%2Fcanada_on_rails_gruff.pdf&amp;ei=2urBR-elJYe6-ALryoX2DA&amp;usg=AFQjCNEc0leNwpB7ai1MeHjDO3eD1T_kiQ&amp;sig2=SgqtwiMT6yb1-zOUqOl8pw"&gt;gruff graphs for ruby by geoffrey grosenbach&lt;/a&gt; [topfunky.com]</description>
      <pubDate>Sun, 24 Feb 2008 18:52:14 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5168</guid>
      <author>jrobertson (James Robertson)</author>
    </item>
    <item>
      <title>install rmagick on leopard</title>
      <link>http://snippets.dzone.com/posts/show/4798</link>
      <description>&lt;code&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;curl -O http://download.savannah.gnu.org/releases/freetype/freetype-2.3.5.tar.gz&lt;br /&gt;tar xzvf freetype-2.3.5.tar.gz&lt;br /&gt;cd freetype-2.3.5&lt;br /&gt;./configure --prefix=/usr/local&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;curl -O http://superb-west.dl.sourceforge.net/sourceforge/libpng/libpng-1.2.22.tar.bz2&lt;br /&gt;tar jxvf libpng-1.2.22.tar.bz2&lt;br /&gt;cd libpng-1.2.22&lt;br /&gt;./configure --prefix=/usr/local&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;curl -O ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz&lt;br /&gt;tar xzvf jpegsrc.v6b.tar.gz&lt;br /&gt;cd jpeg-6b&lt;br /&gt;ln -s `which glibtool` ./libtool&lt;br /&gt;export MACOSX_DEPLOYMENT_TARGET=10.5&lt;br /&gt;./configure --enable-shared --prefix=/usr/local&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;curl -O ftp://ftp.remotesensing.org/libtiff/tiff-3.8.2.tar.gz&lt;br /&gt;tar xzvf tiff-3.8.2.tar.gz&lt;br /&gt;cd tiff-3.8.2&lt;br /&gt;./configure --prefix=/usr/local&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;curl -O http://jaist.dl.sourceforge.net/sourceforge/wvware/libwmf-0.2.8.4.tar.gz&lt;br /&gt;tar xzvf libwmf-0.2.8.4.tar.gz&lt;br /&gt;cd libwmf-0.2.8.4&lt;br /&gt;make clean&lt;br /&gt;./configure&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;curl -O http://www.littlecms.com/lcms-1.17.tar.gz&lt;br /&gt;tar xzvf lcms-1.17.tar.gz&lt;br /&gt;cd lcms-1.17&lt;br /&gt;make clean&lt;br /&gt;./configure&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;curl -O ftp://mirror.cs.wisc.edu/pub/mirrors/ghost/GPL/gs860/ghostscript-8.60.tar.gz&lt;br /&gt;tar zxvf ghostscript-8.60.tar.gz&lt;br /&gt;cd ghostscript-8.60/&lt;br /&gt;./configure  --prefix=/usr/local&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;curl -O ftp://mirror.cs.wisc.edu/pub/mirrors/ghost/GPL/current/ghostscript-fonts-std-8.11.tar.gz&lt;br /&gt;tar zxvf ghostscript-fonts-std-8.11.tar.gz&lt;br /&gt;sudo mv fonts /usr/local/share/ghostscript&lt;br /&gt;&lt;br /&gt;curl -O http://imagemagick.site2nd.org/imagemagick/ImageMagick-6.3.5-9.tar.gz&lt;br /&gt;tar xzvf ImageMagick-6.3.5-9.tar.gz&lt;br /&gt;cd ImageMagick-6.3.5&lt;br /&gt;export CPPFLAGS=-I/usr/local/include&lt;br /&gt;export LDFLAGS=-L/usr/local/lib&lt;br /&gt;./configure --prefix=/usr/local --disable-static --with-modules --without-perl --without-magick-plus-plus --with-quantum-depth=8 --with-gs-font-dir=/usr/local/share/ghostscript/fonts&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;br /&gt;sudo gem install RMagick&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 19 Nov 2007 21:59:39 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4798</guid>
      <author>caffo ()</author>
    </item>
    <item>
      <title>Produce GIF or PNG barcode images from a Ruby on Rails application using RMagick and Gbarcode</title>
      <link>http://snippets.dzone.com/posts/show/4154</link>
      <description>This is a Ruby on Rails controller that produces PNG barcode images using RMagick (http://rmagick.rubyforge.org/) and Gbarcode (http://gbarcode.rubyforge.org/), the Ruby Gnu Barcode ( http://www.gnu.org/software/barcode/barcode.html ) wrapper. You will need to install RMagick and Gbarcode. &lt;br /&gt;&lt;br /&gt;On Mac OS X, you can use the Locomotive RMagick bundle (http://locomotive.raaum.org/bundles/index.html) if you install the gbarcode gem into it first, for instance: &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;% export GEM_HOME=/Applications/Locomotive2/Bundles/rmagickRailsMar2007_i386.locobundle/framework/lib/ruby/gems/1.8/&lt;br /&gt;% gem install gbarcode&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To use it, save this code as barcode_controller.rb in the apps/controllers directory of your Rails application. Generate the barcodes using a URL like this:&lt;br /&gt;&lt;br /&gt;http://localhost:3000/barcode/get_barcode_image?string=foo&lt;br /&gt;&lt;br /&gt;This example uses the BARCODE_128 encoding; you can use different barcode encodings by adjusting the code. To produce PNG images, make sure you have have the PNG libraries installed on your system, and that your ImageMagick is compiled with PNG support, and then change 'image/gif' to 'image/png' and im.format = "GIF" to im.format = "PNG". &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# $RAILS_ROOT/apps/controllers/barcode_controller.rb&lt;br /&gt;class BarcodeController &lt; ApplicationController&lt;br /&gt;&lt;br /&gt;  def get_barcode_image&lt;br /&gt;     string_to_encode = params[:string]&lt;br /&gt;     barcode_image = BarcodeGenerator.get_barcode_image(string_to_encode)&lt;br /&gt;     send_data(barcode_image, :type     =&gt; 'image/gif',&lt;br /&gt;                                  :disposition =&gt; 'inline')&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# $RAILS_ROOT/app/helpers/barcode_generator.rb&lt;br /&gt;#&lt;br /&gt;# note: this will not work without rmagick (Ruby ImageMagick interface) and gbarcode (GNU barcode) &lt;br /&gt;# gems installed. rmagick needs ImageMagick plus dependencies.&lt;br /&gt;&lt;br /&gt;class BarcodeGenerator&lt;br /&gt;&lt;br /&gt;  # Uses subprocesses because &lt;br /&gt;  # 1. ImageMagick/RMagick leaks memory,&lt;br /&gt;  #    and doesn't work in a long-running process. The fork makes it safe.&lt;br /&gt;  # 2. The output from the Gbarcode and ImageMagick is often longer than the pipe buffer,&lt;br /&gt;  #    so we have to empty the buffer from another subprocess&lt;br /&gt;  def BarcodeGenerator.get_barcode_image(barcode_string)&lt;br /&gt;    return BarcodeGenerator.get_subprocess_output do&lt;br /&gt;                   barcode_generator = BarcodeGenerator.new&lt;br /&gt;                   $stdout.write(barcode_generator.get_barcode_image(barcode_string))&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def initialize&lt;br /&gt;    # we do the imports here to protect long-running processes (like mongrel) from ImageMagick's memory leaks&lt;br /&gt;    require 'RMagick'&lt;br /&gt;    require 'gbarcode'&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def get_barcode_image(string_to_encode)&lt;br /&gt;    if string_to_encode.nil?&lt;br /&gt;      string_to_encode = "No string specified"&lt;br /&gt;    end&lt;br /&gt;    string_to_encode = remove_rails_file_extension(string_to_encode)&lt;br /&gt;    eps_barcode = get_barcode_eps(string_to_encode)&lt;br /&gt;    gif_barcode = convert_eps_to_gif(eps_barcode)&lt;br /&gt;    return gif_barcode&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def remove_rails_file_extension(string_to_encode)&lt;br /&gt;    if string_to_encode[-4..-1] == ".png"&lt;br /&gt;      string_to_encode = string_to_encode[0..-5]&lt;br /&gt;    end&lt;br /&gt;    return string_to_encode&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def get_barcode_eps(string_to_encode)&lt;br /&gt;    barcode_object = Gbarcode.barcode_create(string_to_encode)&lt;br /&gt;    Gbarcode.barcode_encode(barcode_object, Gbarcode::BARCODE_128)&lt;br /&gt;    return BarcodeGenerator.get_subprocess_output do&lt;br /&gt;        Gbarcode.barcode_print(barcode_object, $stdout, Gbarcode::BARCODE_OUT_EPS)    &lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def convert_eps_to_gif(eps_image)&lt;br /&gt;    base64_eps_image = Base64.encode64(eps_image)&lt;br /&gt;    im = Magick::Image::read_inline(base64_eps_image).first&lt;br /&gt;    im.format = "GIF"&lt;br /&gt;    return BarcodeGenerator.get_subprocess_output do&lt;br /&gt;       im.write($stdout) &lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  # execute a block's code in a subprocess, returning any output&lt;br /&gt;  def BarcodeGenerator.get_subprocess_output()&lt;br /&gt;    data = ""&lt;br /&gt;    IO.popen('-', 'r+') do |child_filehandle|&lt;br /&gt;      if child_filehandle&lt;br /&gt;        begin&lt;br /&gt;          data = child_filehandle.read&lt;br /&gt;        ensure&lt;br /&gt;          child_filehandle.close_write&lt;br /&gt;        end&lt;br /&gt;      else&lt;br /&gt;        yield&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    return data&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;end    &lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 17 Jun 2007 20:26:31 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4154</guid>
      <author>adamf (Adam Feuer)</author>
    </item>
    <item>
      <title>install rmagick ubuntu</title>
      <link>http://snippets.dzone.com/posts/show/4140</link>
      <description>let's undo some of the damage (just in case):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo apt-get remove --purge librmagick-ruby-doc librmagick-ruby1.8&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Next let's get the version we need:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo apt-get install libmagick9-dev ruby1.8-dev&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Lastly, go grab rmagick, the gem&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo gem install rmagick&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 14 Jun 2007 02:44:18 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4140</guid>
      <author>caffo ()</author>
    </item>
    <item>
      <title>Avatar Resizer</title>
      <link>http://snippets.dzone.com/posts/show/3860</link>
      <description>I go on a lot of Bulletin Board, every has its own limits of size for the avatars, instead of the resize manually I created a script which does it for me with RMagick&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/usr/bin/ruby&lt;br /&gt;require "RMagick"&lt;br /&gt;$SIZES = [80 , 100 , 110 , 128]&lt;br /&gt;&lt;br /&gt;if !ARGV[0]&lt;br /&gt;  puts "Usage: mk_avatars.rb SourceAvatarPath"&lt;br /&gt;  exit&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;image = Magick::Image.read(ARGV[0]).first&lt;br /&gt;$SIZES.each do |sz|&lt;br /&gt;  puts "Generating Avatar : #{sz}"&lt;br /&gt;  out = image.thumbnail(sz,sz)&lt;br /&gt;  file = "out_#{sz}.#{image.format}"&lt;br /&gt;  out.write(file)&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 23 Apr 2007 17:13:46 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3860</guid>
      <author>kedare (Mathieu Poussin)</author>
    </item>
    <item>
      <title>Garmin Forerunner TCX file processing</title>
      <link>http://snippets.dzone.com/posts/show/3712</link>
      <description>This is a small ruby file I wrote to process the TCX file that I can download from MotionBased website that is processed from the data off my Garmin Forerunner 305.  It processes the XML file and generates a little badge/infographic that I can put on a website.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;// insert code here..&lt;br /&gt;require "date"&lt;br /&gt;require "rexml/document"&lt;br /&gt;require 'rubygems'&lt;br /&gt;require 'RMagick'&lt;br /&gt;&lt;br /&gt;class ForeRunner&lt;br /&gt;  &lt;br /&gt;  M2MI = 1609.344 # meters to miles&lt;br /&gt;  MINIMUM_LAP_TIME = 300 # minimum seconds to count as a full lap&lt;br /&gt;  &lt;br /&gt;  attr_accessor :laps, :total_time, :distance, :calories&lt;br /&gt;  &lt;br /&gt;  def initialize(file)&lt;br /&gt;    @source_doc = REXML::Document.new file&lt;br /&gt;    &lt;br /&gt;    @laps = 0&lt;br /&gt;    @lap_times = Array.new&lt;br /&gt;    @lap_bpm = Array.new&lt;br /&gt;    @full_laps = 0&lt;br /&gt;&lt;br /&gt;    @total_time = 0    &lt;br /&gt;    @distance = 0&lt;br /&gt;    @calories = 0&lt;br /&gt;    @map_data = []&lt;br /&gt;    &lt;br /&gt;    self.process_file  &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def generate_infographic(output_filename)&lt;br /&gt;    canvas = Magick::Image.new(250, 80)&lt;br /&gt;    map_size = 50&lt;br /&gt;    map_color = 'green'&lt;br /&gt;&lt;br /&gt;    max_lap_height = 25&lt;br /&gt;    &lt;br /&gt;    gc = Magick::Draw.new&lt;br /&gt;&lt;br /&gt;    # Draw ellipse&lt;br /&gt;    gc.stroke('grey50')&lt;br /&gt;    gc.stroke_width(2)&lt;br /&gt;    gc.fill_opacity(0)&lt;br /&gt;&lt;br /&gt;    # draw the relative lap times&lt;br /&gt;    lap = 0&lt;br /&gt;    max_time = @lap_times.max&lt;br /&gt;    @lap_times.each do |s|&lt;br /&gt;      lap += 1&lt;br /&gt;      x = 10 + (lap * 5)&lt;br /&gt;      y = 60 - (s / (max_time / max_lap_height))&lt;br /&gt;      gc.line(x, 60, x, y)&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    #draw the heartbeat avg&lt;br /&gt;    gc.stroke('#c9a')&lt;br /&gt;    &lt;br /&gt;    lap = 0&lt;br /&gt;    lx = nil&lt;br /&gt;    ly = nil&lt;br /&gt;    max_bpm = @lap_bpm.max&lt;br /&gt;    min_bpm = @lap_bpm.min&lt;br /&gt;    &lt;br /&gt;    max_bpm_height = 18&lt;br /&gt;    &lt;br /&gt;    @lap_bpm.each do |s|&lt;br /&gt;      lap += 1&lt;br /&gt;      x = 10 + (lap * 5)&lt;br /&gt;      y = 21 - ( (s - min_bpm) / ((max_bpm - min_bpm) / max_bpm_height))&lt;br /&gt;      if !lx&lt;br /&gt;        lx = x&lt;br /&gt;        ly = y&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;      gc.line(lx, ly, x, y)&lt;br /&gt;&lt;br /&gt;      lx = x&lt;br /&gt;      ly = y&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    # draw the map&lt;br /&gt;    lat_diff = (@map_data['max_lat'] - @map_data['min_lat']).abs&lt;br /&gt;    lon_diff = (@map_data['max_lon'] - @map_data['min_lon']).abs&lt;br /&gt;&lt;br /&gt;    lat_off = lat_diff / map_size&lt;br /&gt;    lon_off = lon_diff / map_size&lt;br /&gt;    &lt;br /&gt;    gc.fill(map_color)&lt;br /&gt;    @map_data['map_data'].each do |i|&lt;br /&gt;      lt = (map_size - ((i[0] - @map_data['min_lat']) / lat_off)).round&lt;br /&gt;      lg = ((i[1] - @map_data['min_lon']) / lon_off).round&lt;br /&gt;      gc.point((240 - map_size) + lg, (65 - map_size) + lt)&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    # Annotate&lt;br /&gt;    gc.stroke('transparent')&lt;br /&gt;    gc.fill('black')&lt;br /&gt;    gc.text(120, 15, @distance.to_s[0, 5] + ' mi')&lt;br /&gt;    gc.text(120, 30, (@total_time / 60 / 60).to_s[0, 4] + ' hr')&lt;br /&gt;    gc.text(120, 45, @calories.to_s + ' cal')&lt;br /&gt;&lt;br /&gt;    gc.fill('#555')&lt;br /&gt;    total_hr = 0 &lt;br /&gt;    @lap_bpm.each { |hr| total_hr += hr }&lt;br /&gt;    gc.text(15, 32, 'avg bpm: ' + (total_hr / @laps).round.to_s)&lt;br /&gt;    gc.text(15, 75, 'avg pace: ' + ((@total_time / @full_laps) / 60).to_s[0, 4] + ' min/lap')&lt;br /&gt;&lt;br /&gt;    gc.draw(canvas)&lt;br /&gt;    canvas.write(output_filename)&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  protected &lt;br /&gt;  &lt;br /&gt;  def process_file&lt;br /&gt;    @source_doc.elements.each('TrainingCenterDatabase/Activities/Activity/Lap/*') do |element| &lt;br /&gt;      if element.name == "TotalTimeSeconds"&lt;br /&gt;        @lap_times &lt;&lt; element.text.to_f&lt;br /&gt;        if element.text.to_f &gt; 300  # for removing warmup and warmdown laps&lt;br /&gt;          @total_time += element.text.to_f&lt;br /&gt;          @full_laps += 1&lt;br /&gt;        end&lt;br /&gt;        @laps += 1&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;      if element.name == "DistanceMeters" &lt;br /&gt;        @distance += (element.text.to_f / M2MI)&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;      if element.name == "Calories" &lt;br /&gt;        @calories += element.text.to_f&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;      if element.name == "AverageHeartRateBpm" &lt;br /&gt;        element.elements.each('Value') { |v| @lap_bpm &lt;&lt; v.text.to_f }&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    @map_data = self.generate_map_points&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def generate_map_points  &lt;br /&gt;    map = []&lt;br /&gt;&lt;br /&gt;    max_lat = -300&lt;br /&gt;    max_lon = -300&lt;br /&gt;    min_lat = 300&lt;br /&gt;    min_lon = 300&lt;br /&gt;&lt;br /&gt;    @source_doc.elements.each('TrainingCenterDatabase/Activities/Activity/Lap/Track/Trackpoint/*') do |element|&lt;br /&gt;      if element.elements['LatitudeDegrees']&lt;br /&gt;        lat = element.elements['LatitudeDegrees'].text.to_f&lt;br /&gt;        lon = element.elements['LongitudeDegrees'].text.to_f&lt;br /&gt;&lt;br /&gt;        map &lt;&lt; [lat, lon]&lt;br /&gt;        max_lat = lat if (lat &gt; max_lat) &lt;br /&gt;        max_lon = lon if (lon &gt; max_lon) &lt;br /&gt;        min_lat = lat if (lat &lt; min_lat) &lt;br /&gt;        min_lon = lon if (lon &lt; min_lon) &lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    {'map_data' =&gt; map, 'max_lat' =&gt; max_lat, 'min_lat' =&gt; min_lat, 'max_lon' =&gt; max_lon, 'min_lon' =&gt; min_lon}&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if ARGV[0].nil? &lt;br /&gt;  puts "This program takes one argument, a Garmin Forerunner TCX File"&lt;br /&gt;  puts "Like this: run.rb filename.tcx"&lt;br /&gt;  exit&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;output_filename = ARGV[0].gsub(/\.tcx$/, "-" + Time.now.strftime("%Y%m%d") + ".png")&lt;br /&gt;puts "Generating Graph #{output_filename}"&lt;br /&gt;&lt;br /&gt;fr = ForeRunner.new(File.new(ARGV[0]))&lt;br /&gt;fr.generate_infographic(output_filename)&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 21 Mar 2007 19:05:29 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3712</guid>
      <author>schacon (Scott Chacon)</author>
    </item>
    <item>
      <title>generic file and image models for uploaded files</title>
      <link>http://snippets.dzone.com/posts/show/793</link>
      <description>These are basic models that store a file in a dedicated files table.  Use has_one or has_many to associate this with your actual models.  RMagick is required for images.&lt;br /&gt;&lt;br /&gt;This is my first code dealing with uploads and rmagick, so please comment if you have suggestions.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;class DbFile &lt; ActiveRecord::Base&lt;br /&gt;  IMAGE_TYPES = ['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png']&lt;br /&gt;  before_validation     :sanitize_filename&lt;br /&gt;  validates_presence_of :size, :filename, :content_type&lt;br /&gt;&lt;br /&gt;  class &lt;&lt; self&lt;br /&gt;    def new_file(file_data)&lt;br /&gt;      content_type = file_data.content_type.strip&lt;br /&gt;      (IMAGE_TYPES.include?(content_type) ? DbImage : DbFile).new \&lt;br /&gt;        :data         =&gt; file_data.read,&lt;br /&gt;        :filename     =&gt; file_data.original_filename,&lt;br /&gt;        :size         =&gt; file_data.size,&lt;br /&gt;        :content_type =&gt; content_type&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  protected&lt;br /&gt;  def sanitize_filename&lt;br /&gt;      # NOTE: File.basename doesn't work right with Windows paths on Unix&lt;br /&gt;      # get only the filename, not the whole path&lt;br /&gt;      filename.gsub! /^.*(\\|\/)/, ''&lt;br /&gt;&lt;br /&gt;      # Finally, replace all non alphanumeric, underscore or periods with underscore&lt;br /&gt;      filename.gsub! /[^\w\.\-]/, '_'&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;require 'rmagick'&lt;br /&gt;require 'base64'&lt;br /&gt;class DbImage &lt; DbFile&lt;br /&gt;  def data=(file_data)&lt;br /&gt;    with_image(file_data, true) do |img|&lt;br /&gt;      self.width  = img.columns&lt;br /&gt;      self.height = img.rows&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def with_image(file_data = nil, save_image = false, &amp;block)&lt;br /&gt;    img = Magick::Image::read_inline(Base64.b64encode(file_data || self.data)).first&lt;br /&gt;    block.call(img)&lt;br /&gt;    write_attribute('data', img.to_blob) if save_image&lt;br /&gt;    img = nil&lt;br /&gt;    GC.start&lt;br /&gt;  end&lt;br /&gt;end&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Controller Usage:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# returns DbImage if content_type matches&lt;br /&gt;db_file = DbFile.new_file(params[:file][:data])&lt;br /&gt;db_file.save&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Model Usage:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# raw binary image data&lt;br /&gt;File.open('my_file', 'w') { |f| f.write(db_file.data) }&lt;br /&gt;&lt;br /&gt;# Image resizing with rmagick&lt;br /&gt;# automatically creates RMagick::Image and &lt;br /&gt;# invokes GC.start&lt;br /&gt;db_file.with_image do |img|&lt;br /&gt;  img.scale(.25)&lt;br /&gt;  img.write('thumb.jpg')&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sat, 08 Oct 2005 05:31:43 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/793</guid>
      <author>technoweenie (Rick Olson)</author>
    </item>
    <item>
      <title>On-the-fly thumbnailer method for a Rails 'Photo' controller</title>
      <link>http://snippets.dzone.com/posts/show/71</link>
      <description>&lt;code&gt;&lt;br /&gt;require 'RMagick'&lt;br /&gt;&lt;br /&gt;class PhotoController &lt; ApplicationController&lt;br /&gt;&lt;br /&gt;[...snip...]&lt;br /&gt;&lt;br /&gt;    def render_resized_image&lt;br /&gt;                @photo=Photo.find(@params["id"])&lt;br /&gt;&lt;br /&gt;                maxw = @params["width"] != nil ? @params["width"].to_i : 90&lt;br /&gt;                maxh = @params["height"] != nil ? @params["height"].to_i : 90&lt;br /&gt;                aspectratio = maxw.to_f / maxh.to_f&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;                pic = Magick::Image.from_blob(@photo.image)[0]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;                picw = pic.columns&lt;br /&gt;                pich = pic.rows&lt;br /&gt;                picratio = picw.to_f / pich.to_f&lt;br /&gt;&lt;br /&gt;                if picratio &gt; aspectratio then&lt;br /&gt;                        scaleratio = maxw.to_f / picw&lt;br /&gt;                else&lt;br /&gt;                        scaleratio = maxh.to_f / pich&lt;br /&gt;                end&lt;br /&gt;&lt;br /&gt;                #breakpoint&lt;br /&gt;&lt;br /&gt;                thumb = pic.resize(scaleratio)&lt;br /&gt;&lt;br /&gt;                @response.headers["Content-type"]=@photo.mime&lt;br /&gt;    end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;p&gt;Requires &lt;a href="http://rmagick.rubyforge.org/"&gt;RMagick&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Based on &lt;a href="http://www.bigbold.com/snippets/posts/show/36"&gt;Thumbnailer in Ruby and RMagick&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Fri, 08 Apr 2005 06:47:20 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/71</guid>
      <author>jazzido (Manuel Aristar&#225;n)</author>
    </item>
    <item>
      <title>Thumbnailer in Ruby and RMagick</title>
      <link>http://snippets.dzone.com/posts/show/36</link>
      <description>&lt;code&gt;require 'RMagick'&lt;br /&gt;&lt;br /&gt;maxwidth = 120&lt;br /&gt;maxheight = 160&lt;br /&gt;aspectratio = maxwidth.to_f / maxheight.to_f&lt;br /&gt;imgfile = 'world'&lt;br /&gt;&lt;br /&gt;pic = Magick::Image.read(imgfile + '.jpg').first&lt;br /&gt;imgwidth = pic.columns&lt;br /&gt;imgheight = pic.rows&lt;br /&gt;imgratio = imgwidth.to_f / imgheight.to_f&lt;br /&gt;imgratio &gt; aspectratio ? scaleratio = maxwidth.to_f / imgwidth : scaleratio = maxheight.to_f / imgheight&lt;br /&gt;thumb = pic.resize(scaleratio)&lt;br /&gt;&lt;br /&gt;white_bg = Magick::Image.new(maxwidth, thumb.height)&lt;br /&gt;pic = white_bg.composite(thumb, Magick::CenterGravity, Magick::OverCompositeOp)&lt;br /&gt;pic.write(imgfile + '.thumb.jpg')&lt;/code&gt;</description>
      <pubDate>Mon, 04 Apr 2005 06:41:44 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/36</guid>
      <author>peter (Peter Cooperx)</author>
    </item>
  </channel>
</rss>
