Thursday, January 3, 2008

Ruby, pipes and RMagick

I wanted to be able to run the following:

ls *.jpg | grep -v small | ruby thumbnailise.rb

This command lists all jpg files, excludes the ones that were already converted (thumbnailisied) and calls a Ruby script passing the files using a pipeline.
In order to do that I had to find a way of using Unix pipelines in Ruby. The solution is using STDIN.readlines:

require 'RMagick'
require 'pathname'

input = STDIN.readlines
input.each do |line|
filename = line.strip
image = Magick::Image.read(filename).first
image.crop_resized!(100, 100, Magick::NorthGravity)
path = Pathname.new(filename)
outFile = "#{path.basename(".jpg")}_small#{path.extname}"
image.write(outFile)
end


Do you know any nicer solutions how to do that?

4 comments:

  1. How about using -n switch?

    ReplyDelete
  2. Thanks, szeryf!

    With the -n switch I can get rid of the while loop and access the input line with $_ (it comes as an array). Much better.

    require 'RMagick'
    require 'pathname'

    filename = $_.split.first
    image = Magick::Image.read(filename).first
    image.crop_resized!(100, 100, Magick::NorthGravity)
    path = Pathname.new(filename)
    outFile = "#{path.basename(".jpg")}_small#{path.extname}"
    image.write(outFile)

    ReplyDelete
  3. I think you could have avoided the loop by using xargs.

    ReplyDelete
  4. How about Dir["*.jpg"].reject{|fn| fn =~ /small/}.each{|fn| ... } ?

    With Ruby standard library and FileUtils you can do most of the stuff shell does much more easily.

    ReplyDelete