« January 2006 | Main | March 2006 »

February 21, 2006

Animation of embedded images

Following on from my previous post on Embedding data within HTML I thought it might be interesting to see if you could use client-side JavaScript to modify the embedded data in a useful manner. It turns out that modifying the palette of a GIF image is not very difficult, so here is a proof of concept that demonstrates how this colour change can be effected.

You can see the code by viewing the source of this page. The main interesting component (copied below) is that the colours are set by modifying a few particular bytes. Specifically, the hex value of red is set at bytes 43 & 44, green at 46 & 47 and blue at 49 & 50 of my data element. Knowing that, the reading and writing of particular colours is elementary.

function setColour(data, red, green, blue) {
	dataOffset = 43;
	return(
              data.substr(0, dataOffset) + 
              inHex(red) + '%' + 
              inHex(green) + '%' + 
              inHex(blue) + 
              data.substr(dataOffset + 8)
	);
}

An enterprising programmer could no doubt use this to animate a rather more complex image. However, JavaScript is a pretty slow language, so the size of the image and the animation speed would probably be quite limited.

Again I apologise to users of Internet Explorer, but your browser is too old for this demonstration.

February 19, 2006

Embedding data within HTML

After creating the interesting, though perhaps ultimately slightly pointless, online Asciifier recently, I was intrigued to learn of another method of inserting image data directly into an HTML page. The underused data:URI scheme involves a straightforward encoding a small amounts of data. The smallest example I could come up with is this 1x1 white pixel.

<img src='data:image/gif;base64,R0lGODdhAQABAIAAAP///////yw
AAAAAAQABAAACAkQBADs='/>

Once again downtrodden users of the ancient Internet Explorer 6 are left out in the cold, as that browser is not in tune with such modern lingo as this. People viewing this page with less antiquated software will now see a delightful image from the great Henry Fuseli - Silence, 1799-1801.

Despite being around for a number of years, data:URI has not been extensively used. Is this because it's not well-known, or because it's not very useful? I'm afraid it may be the latter, and until Internet Explorer supports it, it will remain a toy for internet nerds alone.

February 18, 2006

Global warming tipping point

It has been over a year since an ominous report warned of "climatic tipping points'', such as the Greenland and West Antarctic ice sheets melting and the Gulf Stream shutting down, if action on stopping global warming was not taken soon. Meeting the Climate Challenge called on the G-8 leading industrial nations to cut carbon emissions, double their research spending on green technology and work with India and China to build on the Kyoto Protocol.

LiveScience mentions:

According to the report, urgent action is needed to stop the global average temperature rising by 2 degrees Celsius above the level in 1750 -- the approximate start of the Industrial Revolution when mankind first started significantly polluting the atmosphere with carbon dioxide.

No accurate temperature readings were available for 1750, the report said, but since 1860, global average temperature had risen by 0.8 percent to 15 degrees Celsius.

The two degrees rise could be avoided by keeping the concentration of carbon dioxide in the atmosphere below 400 parts per million (ppm). Current concentrations of 379 ppm "are likely to rise above 400 ppm in coming decades and could rise far higher under a business-as-usual scenario,'' the report warned.

Atmospheric carbon dioxide (parts per million)
1750 275
2005 380
Tipping point 400

The tipping point value mentioned is only an guess estimate. Perhaps it'll turn out to be 381ppm, or 450ppm. Whatever it is, if we don't stop pumping out greenhouse gases at the current rate, we'll definitely reach it. It's just a matter of time.

February 16, 2006

Asciifier

I've added an image asciifier tool to the Chaucery fun area of this site. It converts given images into text only representations, and can work on uploaded files, direct URLs to images, or even convert the images on a web page in situ.

The coloured asciified images are created using HTML colour codes, but the black and white ones are more oldskool, using different characters to represent different intensities.

Traps for the unwary

The main caveat to watch out for is that large images can result in very large html pages. The asciifier tries to minimise these problems by automatically limiting sizes, but there is an option for the adventurous to override these limits. As the asciifier works its way through the images in a page, it will progressively reduce their resolution if the page size limit will otherwise be exceeded.

There is also a limit on the number of images within a single page that will be converted, with the remaining images left blank. If there is a particular image that you wish to convert that the asciifier does not reach then input the URL to that image directly.

Images containing colons (excluding any initial http://) are not converted - it's a feature, not a bug.

The size and width specified in the img tag are currently ignored, so when these don't match the actual image dimensions the latter wins out.

Conclusion

Whilst I can't actually think of any reason to want to convert images into HTML, I think it is interesting that pixel perfect copies can be created in human readable and editable form, which is really what the World Wide Web is all about.

February 9, 2006

Convert RealAudio to MP3

Download realToMp3.py

RealAudio streams are not very easy to convert to mp3 files. There are some shareware tools that claim to perform the task, but with a little bit of effort you can set up a really simple system yourself for free. Here I shall document how to set up a really easy to use converter for Windows.

The end result is this lovely simple dialog for interactive downloading, or you could set up a scheduled task to grab a RealAudio stream and save it as an MP3 with no user input at all.

There is a price to pay for getting all this for free, and that is that there is no simple one-step installer. Instead, we are going to set up a variety of free tools, and tie them all together with some scripting. Here's the menu:

  1. Retrieve stream with MPlayer
  2. Convert to MP3 with LAME
  3. Automate the previous steps using Python
  4. Add a nice interface with Windows Scripting Host

Part 1: Retrieve stream with MPlayer

MPlayer is a highly regarded Open Source audio and video player. Once you've downloaded and installed it you can test that it's working from the good old command prompt:

mplayer -cache 320 -ao pcm:waveheader:file=stream.wav rtsp://some.stream.ra

Note that you need to pass a .ra or .rm stream. If you have a .ram stream instead, then save that as a local file and have a look in it with a text editor such as notepad to see the actual stream name.

If this does not work then take careful note of the error messages being emitted. This was the point at which I learnt that I needed to download some RealAudio CODECS from the MPlayer site, which were then unzipped into MPlayer's CODEC's folder.

Once you've got this going you'll see the one unavoidable annoyance, that you can't download any faster than the normal stream listening time. Anyway, the result of this is that you have converted a RealAudio stream to a probably rather large .wav file. Now we need to shrink that to a reasonably-sized MP3 file.

Part 2: Convert to MP3 with LAME

LAME is a popular Open Source MP3 encoder. We need the standard windows LAME binaries, which aren't provide by the LAME site, but a quick Google search will provide places such as this. Install it, and test from the command line again:

lame -b 64 stream.wav stream.mp3

That's the hard stuff done. If you don't mind going to the command line and doing some manual labour each time you want to save a stream then you can stop here. However, if you want to make your life easier in future, then you may wish to script those commands.

Part 3: Join parts 1 and 2 with Python

Jkx wrote a little Python script in 2004 to automate the MPlayer and LAME processes, and to parse the stream from the .ram file. Due to bit rot this no longer works, so I made a few small fixes and minor improvements to create realToMp3.py.

To run this you'll need the Open Source scripting language Python installed. Unlike the previous two packages this comes with a nice easy installer. Note that the locations of MPlayer and LAME are hard-coded in the script, so you'll need to edit these. You can use any text editor, but make sure you only ever use spaces, not tabs, or Python will complain. You can also edit the folder in which the resultant mp3s are saved.

Again you can test this from the command line:

realToMp3.py http://location.of.stream.ram

Part 4: Add GUI with Windows Scripting Host

Finally, if you want a nice icon on your desktop, and an easy interface to use your python script, then you can use this very short Windows Script (the successor to batch files), realToMp3.vbs. [Aside: Visual Basic Script (.vbs) may be yucky, but it has the crucial InputBox() command that JScript (.js) lacks.] If it's in the same folder as the python script then it should work without alteration. Then just create a shortcut to that script on your desktop, and set its icon to something nice.

Conclusion

On reflection it's a little odd to use two scripting languages to accomplish this task. However, trying to do parts 3 and 4 in the same language presents some interesting difficulties. I leave this as homework for the reader. In any case, it's extremely satisfying setting up this system instead of paying US$20 for some easier-to-install but harder-to-configure all-in-one software.

Updated 25-Feb-2006 Python script: Destination folder now works properly.

Updated 15-Oct-2006 Python script: Now works for URLs with querystrings.

Updated 9-Apr-2007 Python script: Added podcast support (read more).