Fun times with RMagick

I was bored the other night, so Dan W and Julian and I had a bit of a hack-night session. Dan was working on Doppmaxion, which looks awesome, and Julian and I took the opportunity to do a little bit of Ruby hacking. What did we get up to, you ask?

Well, if you’re in a decent browser such as Safari or Chrome, and using a fairly powerful computer, check out this. It’s an HTML representation of an image, where by “HTML representation” I mean HTML-as-pixels, and by “an image”, I mean “this is such a bad idea it’s not even funny.”

For a long time, I’ve toyed with the idea of representing image data using HTML elements, so it was great to really unwind and see what Ruby can do with something like this. RMagick, it so happens, has an each_pixel method – which you can use to iterate through the pixels of an image. Although we’re not used to doing this sort of thing in Ruby, it’s actually not that slow – I guess it’s using some ImageMagick cleverness behind the scenes. So I iterated through these pixels and threw them in an array – then iterated through the array and spat out some HTML, one div per pixel. The result? Pandemonium.

Your average browser isn’t really designed handle this kind of abuse. So I had to make things more efficient somehow. In reality, nothing could make this efficient, but I had to try. So if you run through each pixel, you eventually find that a lot of images have runs of pixels that are all the same colour. For those, we could do a <div style=“width: Xpx”> and have one element where we’d otherwise have X! This is called Run-length encoding. If I wanted to be extra-smart, I’d make big square areas of colour into single elements, but that’s a bit complicated for a one-night hack.

The original idea was actually to represent a whole website like this – and if you visit elliottkember.com/awesome you’ll see that I was, in fact, successful. This has the advantage of being pixel-perfect in every browser (although I hear Opera doesn’t do it properly, surprise surprise) – but the disadvantage of murdering every browser known to man. I was going to put this as my actual site, but thought better of it.

The source is available on GitHub, on the off-chance that you can think of something useful for this idiocy. Side note: appending to a file every cycle turned out to be much faster than throwing around 11MB strings in Ruby. Take from that what you will.

Anyway, it just goes to show that just because you can do it, and you think it’s a good idea, sometimes you shouldn’t – and sometimes it isn’t.

Comments (4)

For bonus points you should encode a message in the html element names...

Skilldrick_n Nick Morgan (@skilldrick)
about 1 year ago

Thanks for the explanation and behind-the-scenes - fascinating stuff, regardless of its questionable usefulness! *applause*

Iamkeir_n iamkeir (@iamkeir)
about 1 year ago

Ha! Great work Elliot. I'd love to say I could think of a use for this but I'm stumped, quite possibly the craziest hack session I've seen in a while :)

Tholder_n Tom Holder (@tholder)
about 1 year ago

I nearly have an idea for this technique!

Think emails. A large problem with emails is images not being shown by default. Solution, build the image up with either table cells or divs! We also added the idea of giving a blur multiplier to make the end-product code much smaller.

I kind of works...

The idea came after reading this http://www.campaignmonitor.com/blog/post/3574/image-blocking-in-email-clients-2011/

Joe_turner_n Joe Turner (@joe_turner)
6 months ago