June 16, 2007 by alex
Im ersten Teil habe ich gezeigt, wie man mit file_column in Rails automatisch andere Bilder zu einem Bild hinzufügt, um z.B. Rahmen oder Hintergründe hinzuzufügen.
In diesem Teil geht es darum, auch Text in ein Bild schreiben zu können: Hierbei ergeben sich zwei Probleme. Zum einen muss der Text vom Model in die file_column-Klassen gelangen, zum anderen muss er dort via RMagick in das Bild gerendert werden. Das Ergebnis könnte dann z.B. so aussehen (autoki-Quartettkarte):
Fangen wir von hinten an, RMagick.
Die Beschreibung des Texts im Model soll folgendermaßen aussehen:
file_column :photo, :magick => { :versions =>
{
:badge => {:name => "badge", :text =>
{
:text => 'hello world',
: x => 10,
:y => 241,
:color => '#363636',
:size => 9
}
}
}}
Hierbei soll an die Koordinaten 10/241 der text hello world in der Schriftgröße 9 und in Dunkelgrau gerendert werden.
Um den Text in unser Bild rendern zu können, erweitern wir wieder die transform_image
-Methode in der Datei magick_file_column.rb des file_column-Plugins:
if img_options[:composite]
...
end
if img_options[:text]
if img_options[:text].is_a?(Array)
img_options[:text].each do |text_options|
img = add_text text_options, img
end
else
img = add_text img_options[:text], img
end
end
def add_text(text_options, img)
text = text_options[:text]
unless text.blank?
img = img.annotate ::Magick::Draw.new, 0, 0, text_options[: x], text_options[:y], text do
self.pointsize = text_options[:size] || 11
self.font_weight = text_options[:weight] || 400
self.fill = text_options[:color] || 'black'
end
end
img
end
Das war’s eigentlich auch schon - jetzt haben wir ein hello world in unserem Bild. Teil 2…
Neben statischem text wollen wir auch dynamische Inhalte in unsere Bilder rendern. Wie auf der Autokarte oben zu sehen, rendern wir hier den Namen und die Leistungsdaten des Autos, die bei autoki aus der Datenbank kommen.
Leider gibt es dabei ein kleines Problem: Die Definition der file_column-Bildgrößen hängen nicht an der Model-Instanz, sondern an der Model-Klasse, d.h. an der Stelle, an der wir die Texte definieren, stehen die Daten aus der Datenbank noch gar nicht zur Verfügung. Folgendes funktioniert also nicht.
file_column :photo, :magick => { :versions =>
{
:badge => {:name => "badge", :text =>
{
:text => "#{self.top_speed} km/h",
:x => 10,
:y => 241,
}
}
}}
Stattdessen müssen wir einen kleinen Umweg gehen, wir verwenden Procs, die erst zur Laufzeit der Anwendung den Text generieren:
file_column :photo, :magick => { :versions =>
{
:badge => {:name => "badge", :text =>
{
:text => Proc.new {|model| "#{model.top_speed} km/h"},
:x => 10,
:y => 241,
}
}
}}
Damit das ganze funktioniert, muss file_column noch etwas erweitert werden. Zum einen muss die add_text
-Methode die Procs aufrufen:
def add_text(text_options, img)
text = text_options[:text]
text = text.call(@object) if text.is_a?(Proc)
unless text.blank?
img = img.annotate ::Magick::Draw.new, 0, 0, text_options[:x], text_options[:y], text do
self.pointsize = text_options[:size] || 11
self.font_weight = text_options[:weight] || 400
self.fill = text_options[:color] || 'black'
end
end
img
end
Zum anderen muss die Model-Instanz file_column zur Verfügung gestellt werden. Dazu erweitern wir die Methoden transform_with_magick
und create_magick_version_if_needed
um eine Parameter object
def transform_with_magick(object)
@object = object
..
end
def create_magick_version_if_needed(version, object)
@object = object
..
end
Zuletzt muss noch der Aufruf von create_magick_version_if_needed
in der Methode url_for_image_column
in der Datei file_column_helper.rb angepasst werden:
def url_for_image_column(object, method, options=nil)
..
if options
subdir = object.send("#{method}_state").create_magick_version_if_needed(options, object)
end
..
end
Das war’s. Wenn ich nichts vergessen habe, gibt’s jetzt dynamische Textinhalte in Bildern mit file_column. In einem nächsten Teil dann: Bilderkompression, Amazon S3 Backups.
Wie sehen uns beim Autoquartett.
P.S. Am 5.7. werde ich das ganze bei der Berlin Ruby User Group noch einmal live zeigen, kommt vorbei.
P.P.S. ich schreibe das hier gerade mit der neuen Beta von Safari 3. Vom User vergrößerbare Textareas - Gold wert mit Wordpress.