If have played a little bit with Second Life and its ability to access external resources. Inspired by Matt Biddulph’s “flickr screen”, now I wanted to load XML data from an external source into the SL-world and display it on a nice looking screen. Because it is not possible — from my point of view — to display text directly on a SL-primitive, it was necessary to render the text in a first step to an image. I did this using a little RubyOnRails application which also loads and parses the xml-resource. Ok, now i show how i did this.
I used the REXML processor to work with the XML-data and RMagick to create the image. The xml-source is used is a little XML-file provided by LindenLabs which shows the land sales by resident for the last three month (http://secondlife.com/reports/marketplace_stats/2007-03-01/land_sales_by_residents.xml). The whole parsing is specific to this source.

# get the xml via http and read it into a variable and create a XML-Document after that
@content = Net::HTTP.get(URI.parse("
xmlDoc = REXML::Document.new(@content)

# get some attributes and select them with xpath
elRecords = REXML::XPath.first(xmlDoc, "records")
reportTitle = elRecords.attributes['report']
reportDate = elRecords.attributes['date']

# create a new image in the size you need. in my case it was 400 width and 200 height
f = Image.new(400,200) { self.background_color = "white" }# make some settings for the font
drawable = Magick::Draw.new
drawable.pointsize = 15.0
drawable.font_family = 'Helvetica'
drawable.fill = 'gray'
drawable.gravity = Magick::NorthWestGravity
drawable.font_weight = Magick::BoldWeight
drawable.annotate(f, 0, 0, 5, 4, "Second Life #{reportTitle} (#{reportDate})")
drawable.pointsize = 13.0
drawable.fill = 'black'
drawable.font_weight = Magick::NormalWeight

# set some position for the text i want to print
@startTopPos = 24

# go the records in the xml-document and print the values into the new image
REXML::XPath.each( xmlDoc, "records/record") do |element|
	element.elements.each("field") do |field|
		name = field.attributes['name']
		value = field.attributes['value']
		drawable.annotate(f, 0, 0, 5, @startTopPos, name)
		drawable.annotate(f, 0, 0, 250, @startTopPos, value)
		@startTopPos = @startTopPos + 15
	@startTopPos = @startTopPos + 15

# write the image to the disk. i wasnt able to return it directly without saving. :(
# return the image
createdImg = Magick::Image.read("result.png").first
@response.headers["Content-Type"] = "image/png"
@response.headers['Content-Disposition'] = %q{inline; filename="thepicture.png"}
render :text => createdImg.to_blob

This script returns the following image:

Second Life land sales

To put this image on an primitive i used the following linden script code:

touch_start(integer num_detected) {
    llSay(0, "trying...");

    if(llGetLandOwnerAt(llGetPos()) != llGetOwner()) {
        llSay(0,"Error: Cannot modify parcel media settings.");

    key video_texture = llList2Key(llParcelMediaQuery( [PARCEL_MEDIA_COMMAND_TEXTURE]), 0);

    if(video_texture == NULL_KEY)
        video_texture = VIDEO_DEFAULT;

###URL### has to be replaced with the URL of the Ruby-Script.

Note: To use this ParcelMedia-feature you have to allow streaming media i think in SL.

Reblog this post [with Zemanta]