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:

szeryf said...

How about using -n switch?

Andrzej Krzywda said...

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)

mrquintopolous said...

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

taw said...

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.