[QUIZ#14] Matthias Reitinger (Ruby)

Hallo,

hier mal meine Lösung in Ruby:
Ruby:
#!/usr/bin/env ruby
require 'rubygems'
require 'rmagick'
require 'trollop'

include Magick

# Optionen parsen
options = Trollop::options do
  banner 'Usage: dice.rb [options]'
  text 'Options:'

  opt :input, 'Input image (required)', :required => true, :type => String
  opt :output, 'Output image (required)', :required => true, :type => String
  opt :dice, 'Dice image (required)', :required => true, :type => String
  opt :resize, 'Resize image before processing', :type => String
end

# Würfelbild einlesen und zerschneiden
dices = Image::read(options[:dice]).first
DICE_SIZE = dices.columns
dice = []
6.times do |d|
  dice[d] = dices.crop(0, d*DICE_SIZE, DICE_SIZE, DICE_SIZE)
end

# Eingabebild einlesen
img = Image::read(options[:input]).first

# Eingabebild verkleinern, falls gewünscht
if options[:resize]
  begin
    img.change_geometry(options[:resize]) {|cols, rows| img.resize!(cols, rows) }
  rescue ArgumentError => e
    puts e
    exit(1)
  end
end

# Bild mit den Farben für die Farbreduzierung erzeugen
colors = Image.new(6, 1, GradientFill.new(0, 0, 0, 0, '#000', '#fff'))

# Umwandlung in Graustufen
img = img.
  quantize(256, GRAYColorspace, NoDitherMethod). # in Graustufen umwandeln
  normalize.                                     # Kontrastspreizung
  remap(colors, FloydSteinbergDitherMethod)      # Farbreduzierung mit Dithering

# Ausgabebild anlegen
result = Image.new(img.columns*DICE_SIZE, img.rows*DICE_SIZE)

# Würfel setzen
img.each_pixel do |pixel, x, y|
  i = 5 - (pixel.intensity.to_f/QuantumRange*5).to_i
  result.composite!(dice[i], x*DICE_SIZE, y*DICE_SIZE, CopyCompositeOp)
end

# Ausgabebild schreiben
result.write(options[:output])

Wie ihr seht verwende ich RMagick, die Ruby-Schnittstelle zu ImageMagick. Damit reduzieren sich die Umwandlung in Graustufen, die Kontrastspreizung und die Quantisierung mit Dithering auf ein paar einfache Methodenaufrufe :)

Zum Parsen der Kommandozeilenparameter kommt das schicke Trollop zum Einsatz, was ich vorher noch nicht kannte. Der Grund, warum ich mich nach einer Alternative zum Standardbibliothek-Bestandteil optparse umgeschaut habe, ist simpel: die Parameterdefinition mit optparse war länger als der Rest des Skripts und hätte somit nur vom Wesentlichen abgelenkt.

Ein Beispielaufruf:
Code:
ruby dice.rb -i Me_by_miss_mosh.jpg -o me.png -d wuerfel9-2.png -r 150

Mit dem Quellbild http://miss-mosh.deviantart.com/art/Me-107120469 ergibt das folgende Ausgabe:
me.png

Grüße,
Matthias
 

Anhänge

  • dice.zip
    926 Bytes · Aufrufe: 17
Zurück