A Color Gradient Webservice
secretGeek .:dot Nuts about dot Net:.
home .: about .: sign up .: sitemap .: secretGeek RSS

A Color Gradient Webservice

(In which I demonstrate a GDI+, asp.net, color gradient webservice which lets you create blend images in firefox, not just IE)

Three strange and interesting technical things have converged on me recently....

If you wish to use this often, Full Source Code is Now Available.

First, I read about a Sparklines webservice that lets you inject funky little sparklines into your html, like this: or like this: , just by specifying an image source url such as:

"http://bitworking.org/projects/sparklines/spark.cgi? type=smooth&d=10,20,30,90,80,70&step=4"

(where those comma separated values are the datapoints in the sparkline!)

Second, I've taken an inordinate fondness to the gradient transformation features of IE, which let you create smooth color gradients. (If you've got IE you can see some at work in the World's 2nd Simplest Code Generator (or if you've got Opera/Firefox you can see evidence of the filters in these screen shots.)

And third, I've downloaded firefox, which doesn't render gradient transformations, because those mozilla kids are fairly fussy about standards compliance and things like that.

So I find myself wishing for a browser-independent way of generating color gradients, and thanks to the sparklines article, and sunday's hangover (cheers jeb), I had an idea.

With a little bit of .Net GDI+ magic, I've managed to generate pixel-thin 'blend' images for use as backgrounds.

So what does it do?

If you call out to my 'web-service' in an IMG tag, like this:

You'll get a result like this:

Basically, a one pixel-wide blend image. Here, i'll stretch it out wide to make it easier to see:

By changing the query string around, you can have any start and end color you want, you can go horizontal or vertical. Plus a few other options.

Tastes better with CSS

Like most things in life, this tastes better with CSS. Use the service (or the test page) to create an image for you, then save it to your server. Set it as the background-color (sic.) using CSS. For 'V' (vertical) images, specify a repeat direction of Y. For 'H' (horizontal) images, specify a repeat direction of X.

Warning! Use this service to generate images ONCE, and store them on your own server. I'd rather you didn't use the webservice to generate images dynamically from within your webpages! I may not be able to afford the bandwidth -- and I reserve the right to alter the service to output nasty images, as a retaliation against bandwidth hogs, at any moment.

To Test the Service...

Use this rather natty little test page to test the service. I have, for once in my damn life, tested it on two different browers. So, with luck, it might work.

Here are some samples of the webservice in use:

image: http://secretgeek.net/Gradient.aspx?Direction=H&Length=100&StartColor=00FFFF&EndColor=00FF00&Format=jpeg
image: http://secretgeek.net/Gradient.aspx?Direction=H&Length=100&StartColor=FF0000&EndColor=000000&Format=jpeg
image: http://secretgeek.net/Gradient.aspx?Direction=H&Length=100&StartColor=FFFF00&EndColor=000000&Format=jpeg
image: http://secretgeek.net/Gradient.aspx?Direction=V&Length=300&StartColor=0088FF&EndColor=FFFFFF&Format=jpeg
image: http://secretgeek.net/Gradient.aspx?Direction=V&Length=100&StartColor=FFFFFF&EndColor=0088FF&Format=jpeg
image: http://secretgeek.net/Gradient.aspx?Direction=H&Length=100&StartColor=FF0000&EndColor=FF8800&Format=jpeg

Parameters...

Parameter Description
Direction V for vertical or H for horizontal. Not sure which is which...
Length How long should the image be? It will always have a breadth of 1-pixel. (Whether Length refers to height or width, depends on whether the image is vertical or horizontal!)
StartColor The rgb value of the Starting color, excluding the '#' character.
EndColor The rgb value of the Final color, excluding the '#' character.
Format Jpeg, Gif or Png?

Error Handling

If parameters are wrongly setup, or if something else goes wrong, you get an image like this one:

The Code

Imports System.Drawing

Imports System.Drawing.Drawing2D

 

...

Private Sub Page_Load(ByVal sender As System.Object, _

            ByVal e As System.EventArgs) Handles MyBase.Load

    'Put user code to initialize the page here

    Dim sMessage As String

    Try

        'Parameters:

        Dim _Direction As String 'Horizontal or Vertical

        Dim _Length As Long

        Dim _StartColor As String

        Dim _EndColor As String

        Dim _Format As String

 

        sMessage = "retrieving parameters"

        _Direction = Request.QueryString.Item("Direction")

        _Length = Request.QueryString.Item("Length")

        _StartColor = Request.QueryString.Item("StartColor")

        _EndColor = Request.QueryString.Item("EndColor")

        _Format = Request.QueryString.Item("Format")

 

        Dim lWidth As Integer

        Dim lHeight As Integer

        Dim m_Color1 As Color

        Dim m_Color2 As Color

        Dim myFormat As System.Drawing.Imaging.ImageFormat

        Dim myGradientMode As LinearGradientMode

 

        sMessage = "processing parameters"

 

        'Now use the parameters

        If _Direction.ToUpper.StartsWith("H") Then

            lWidth = 1

            lHeight = _Length

            myGradientMode = LinearGradientMode.Vertical

        Else

            lWidth = _Length

            lHeight = 1

            myGradientMode = LinearGradientMode.Horizontal

        End If

 

        If _Format.ToUpper.StartsWith("J") Then

            myFormat = Imaging.ImageFormat.Jpeg

        Else

            myFormat = Imaging.ImageFormat.Gif

        End If

        sMessage = "determining colors"

        m_Color1 = Color.FromArgb(255, _

                CLng("&H" & _StartColor.Substring(0, 2)), _

                CLng("&H" & _StartColor.Substring(2, 2)), _

                CLng("&H" & _StartColor.Substring(4, 2)))

        m_Color2 = Color.FromArgb(255, _

                CLng("&H" & _EndColor.Substring(0, 2)), _

                CLng("&H" & _EndColor.Substring(2, 2)), _

                CLng("&H" & _EndColor.Substring(4, 2)))

 

        'GO!

        sMessage = "determining size"

        Dim bmpGradient As New Bitmap(lWidth, lHeight)

        Dim m_BrushSize As New Rectangle(0, 0, lWidth, lHeight)

        Dim grBitmap As Graphics = Graphics.FromImage(bmpGradient)

        sMessage = "creating gradient brush"

        Dim myLinearGradientBrush As New LinearGradientBrush( _

                    m_BrushSize, m_Color1, m_Color2, _

                    myGradientMode)

        sMessage = "filling rectangle"

        grBitmap.FillRectangle(myLinearGradientBrush, 0, 0, _

                   lWidth, lHeight)

        sMessage = "saving image to response stream"

 

        'Write the image to the client!!            

        bmpGradient.Save(Response.OutputStream, myFormat)

 

    Catch ex As System.Exception

 

        Dim bmpGradient As New Bitmap(600, 100)

        Dim m_BrushSize As New Rectangle(0, 0, 600, 100)           

        Dim grBitmap As Graphics = Graphics.FromImage(bmpGradient)

        Dim myLinearGradientBrush As New LinearGradientBrush( _

                m_BrushSize, _

                Color.FromArgb(255, 255, 0, 0), _

                Color.FromArgb(255, 0, 0, 0), _

                LinearGradientMode.Vertical)

        grBitmap.FillRectangle(myLinearGradientBrush, 0, 0, _

                600, 100)

        grBitmap.DrawString("Error while " & _

                sMessage & " for '" & Request.UserHostAddress & _

                "'." & vbCrLf & ex.Message, _

                New System.Drawing.Font("Arial", 12, _

                System.Drawing.FontStyle.Italic), _

                System.Drawing.Brushes.White, 10, 12)

        'Write the error message image to the client

        bmpGradient.Save(Response.OutputStream, _

                System.Drawing.Imaging.ImageFormat.Jpeg)

 

    End Try

 

End Sub

 

Related articles

Button Makers





'Tobias' on Fri, 05 Aug 2005 12:08:52 GMT, sez:

Once in a while I come across articles which make me go "Why on earth didn't I think of this ages ago". This is definitely one of them. I'm using gradients everywhere in my web designs - this is going to save me a ton of Photoshop work. Thanks a lot for the idea!



'blameMike' on Fri, 05 Aug 2005 17:32:15 GMT, sez:

Dude... you're my hero.

All kidding aside, that's awesome. Of course I noticed the cool gradient in IE, but none in Firefox. I didn't want to say anything though, as I already bitched about the button. ;)



'adam adobe' on Sat, 06 Aug 2005 09:14:13 GMT, sez:

On behalf of Adobe Photoshop, we insist you take down this webservice.

This is a blatant attempt to put us out of work.



'Tao' on Tue, 09 Aug 2005 02:29:20 GMT, sez:

Well done!

Now I only have a small question:
if you have a look the IE Gradient Filter example:
http://msdn.microsoft.com/workshop/samples/author/filter/gradient.htm

There has two alpha value from 00 to FF on StartColor and EndColor. Can the Color Gradient Webservice support this value too?




'leon' on Tue, 09 Aug 2005 04:05:01 GMT, sez:

sorry Tao -- I hardcode in 255 (i.e. FF) for the alpha value.



'Profx' on Fri, 07 Oct 2005 20:57:46 GMT, sez:

<img src='http://secretgeek.net/Gradient.aspx?Direction=H&Length=150&StartColor=FF00FF&EndColor=00FF00&Format=jpeg'>



'Profx2' on Fri, 07 Oct 2005 21:05:49 GMT, sez:

<TD id=msviRegionGradient1
style="FILTER: progid:DXImageTransform.Profx.Gradient(startColorStr='#4B92D9', endColorStr='#CEDFF6', gradientType='1')"
width="50%"></TD>



'http://' on Fri, 07 Oct 2005 21:07:38 GMT, sez:

FILTER: progid:DXImageTransform.Profx.Gradient(startColorStr='#4B92D9', endColorStr='#CEDFF6', gradientType='1')"



'Microsoft' on Fri, 07 Oct 2005 21:43:48 GMT, sez:

<SCRIPT language=JavaScript>
<!--
function view(){
document.all.item('gra1').filters['DXImageTransform.Microsoft.Gradient'].Enabled=1;
}

function unview(){
document.all.item('gra1').filters['DXImageTransform.Microsoft.Gradient'].Enabled=0;
}

function tate(){
document.all.item('gra1').filters['DXImageTransform.Microsoft.Gradient'].GradientType=0;
}

function yoko(){
document.all.item('gra1').filters['DXImageTransform.Microsoft.Gradient'].GradientType=1;
}

//-->
</SCRIPT>

<DIV id=gra1
style="FILTER: progid:DXImageTransform.Microsoft.Gradient(GradientType=1,StartColorStr=#0000ffff,EndColorStr=#ff000099); WIDTH: 100%; HEIGHT: 100%"><BR><BR>



'Microsoft' on Wed, 12 Oct 2005 12:52:35 GMT, sez:

<style type="text/css">
.grad {
filter: progid:DXImageTransform.Microsoft.Gradient(gradientType=0,startColorStr=yellow,endColorStr=Green);
width: 1010px;
height: 400px;
}
</style>

and

<body class="grad">



'Esempio Corporation' on Mon, 28 Nov 2005 10:57:50 GMT, sez:

<style type="text/css">
<!--
#subheader { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BACKGROUND: url(http://www.esempio.it/Esempio_Filter.jpg) #00CC66 repeat-x left top; PADDING-BOTTOM: 3px; PADDING-TOP: 4px; BORDER-BOTTOM: #f0f0f2 1px solid}
-->
</style>

Questo Metodo semplifica la soluzione Filter che consente di usare di qualche tabella di Modificare alcune cose (Dell'Esempio Pratico della Filter si ottiene così):

<DIV id=subheader>
<table cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr valign="bottom">
<td><a href="http://www.esempio.it/*">Gestisci
il tuo profilo</a> |<a
href="http://www.esempio.it/*"
target="_parent">Contattaci</a></div>
<div><span>&copy;2005 Esempio Corporation. Tutti
i diritti sono riservati.&nbsp;</span><a
href="http://www.esempio.it/*" target="_parent">Note
legali</a> |<a
href="http://www.esempio.it/*">Marchi</a> |<a href="http://www.esempio.it/*"
target="_parent">Informativa sulla privacy</a></div></td>
</tr>
</tbody>
</table>
</DIV>
<table height="58" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr valign="top">
<td><div style="WIDTH: 200px"></div></td>
<td width="100%"></td>
</tr>
</tbody>
</table>
</body>
</html>



'Esempio Corporation' on Mon, 28 Nov 2005 11:06:10 GMT, sez:

<style type="text/css">
<!--
#subheader { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BACKGROUND: url(http://www.esempio.it/Esempio_Filter.jpg) #00CC66 repeat-x left top; PADDING-BOTTOM: 3px; PADDING-TOP: 4px; BORDER-BOTTOM: #f0f0f2 1px solid}
-->
</style>

Autorizzo di modifcare questo indirizzo url(http://www.esempio.it/Esempio_Filter.jpg) e poi modificare i colori # che scegliete i colori desiderati che vi piaciono a tutti gli utenti(Un Utente o qualunque utente).


<DIV id=subheader>
<table cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr valign="bottom">
<td><a href="http://www.esempio.it/*">Gestisci
il tuo profilo</a> |<a
href="http://www.esempio.it/*"
target="_parent">Contattaci</a>
<div><span>&copy;2005 Esempio Corporation. Tutti
i diritti sono riservati.&nbsp;</span><a
href="http://www.esempio.it/*" target="_parent">Note
legali</a> |<a
href="http://www.esempio.it/*">Marchi</a> |<a href="http://www.esempio.it/*"
target="_parent">Informativa sulla privacy</a></div></td>
</tr>
</tbody>
</table>
</DIV>
<table height="58" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr valign="top">
<td><div style="WIDTH: 200px"></div></td>
<td width="100%"></td>
</tr>
</tbody>
</table>
</body>
</html>

E impostate il vostro copyright del vostro sito personalizzato ho dato il toolkit per personalizzare la filter aggiungendo con .jpg e in più i colori personalizzati per ottenere la filter senza che venga salvato la foto jpg. Ti garantisco che la tecnologia funziona perfettamente perchè io lo ho provato e va benissimo. (Provare per credere).



'konq user' on Sun, 04 Jun 2006 07:37:08 GMT, sez:

All this stuff works in Konqueror, the KDE web browser. Thought I'd let you know.



'Thomas Frank' on Fri, 21 Jul 2006 05:02:17 GMT, sez:

Cool work!

Now if you want gradients in your headlines/text too, here's a solution for you:

http://www.thomasfrank.se/text_color_gradients.html



'Eddy' on Mon, 28 Aug 2006 06:31:56 GMT, sez:

Hi,

Is this open source ?, would it be o.k for me to use on a none profit making site ?



'Eddy' on Mon, 28 Aug 2006 08:48:43 GMT, sez:

here's another site with a similar project that
has a third gradient type http://tools.dynamicdrive.com/gradient/ they're not showing their source code though.



'lb' on Mon, 28 Aug 2006 21:21:25 GMT, sez:

Hi eddy -- yep i am willing to send you the source. I will also publish the source in full when i get around it.

meanwhile lots of people have been using this directly -- so i've justed updated it to stop it working temporarily.

see, for example: http://z9.invisionfree.com/R_I_P_2/index.php

I'm flattered that these guys are using my stuff... but i wish they'd do it legitimately!

my favourite is http://www.kargro.org/ -- if only there was an email provided i'd write to him and her, thank him and give him the source!



'Eddy' on Tue, 29 Aug 2006 16:46:21 GMT, sez:

I'm puzzled as to why someone would use your site to show a static gradient on their own site, I mean, how hard is it to save an image of about 1kb in size to the server ?.

If you ban their I.P to that gradient aspx page I'm sure they'll come back to the source and find your post, in anycase, thanks for your offer, I could really use something like this in the future to dynamically create several gradients per session (ideally as a server-side dll).

If you could send the source to pen.email(at)gmail.com I'd really appreciate that, thanks again.



'WPKF' on Tue, 21 Nov 2006 01:57:22 GMT, sez:

Interesting idea.



'Jeff' on Sat, 24 Mar 2007 23:05:07 GMT, sez:

Wow, you are one of the coolest programmers ever. Absolutely brilliant, I love it!



'Stephen' on Wed, 25 Jul 2007 19:10:54 GMT, sez:

I reworked this example into C#, added PNG, Transparency, Diagonal Gradients, and Bell Curve w/Scale and Focus.

Enjoy....

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;



public partial class Gradient : System.Web.UI.Page
{
protected void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
string sMessage = "";
try
{
// Parameters:
string _Direction;
// Horizontal or Vertical
string _Height;
string _Width;
string _StartColor;
string _EndColor;
string _Format;
string _Focus;
String _Scale;

sMessage = "retrieving parameters";
_Direction = Request.QueryString["Direction"];
_Height = Request.QueryString["Height"];
_Width = Request.QueryString["Width"];
_StartColor = Request.QueryString["StartColor"];
_EndColor = Request.QueryString["EndColor"];
_Format = Request.QueryString["Format"];
_Focus = Request.QueryString["Focus"];
_Scale = Request.QueryString["Scale"];

float m_Focus = (float)Convert.ToDecimal(_Focus);
float m_Scale = (float)Convert.ToDecimal(_Scale);
int lWidth = Convert.ToInt32(_Width);
int lHeight = Convert.ToInt32(_Height);
Color m_Color1;
Color m_Color2;
System.Drawing.Imaging.ImageFormat myFormat;
LinearGradientMode myGradientMode;
sMessage = "processing parameters";

if (_Direction.ToUpper().StartsWith("V"))
{
myGradientMode = LinearGradientMode.Vertical;
}
else if (_Direction.ToUpper().StartsWith("H"))
{
myGradientMode = LinearGradientMode.Horizontal;
}
else if (_Direction.ToUpper().StartsWith("L"))
{
myGradientMode = LinearGradientMode.BackwardDiagonal;
}
else
{
myGradientMode = LinearGradientMode.ForwardDiagonal;
}

if (_Format.ToUpper().StartsWith("J"))
{
myFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
}
else if (_Format.ToUpper().StartsWith("G"))
{
myFormat = System.Drawing.Imaging.ImageFormat.Gif;
}
else
{
myFormat = System.Drawing.Imaging.ImageFormat.Png;
}
sMessage = "determining colors";

if (_StartColor.ToUpper().StartsWith("T"))
{
m_Color1 = Color.Transparent;
}
else
{
m_Color1 = Color.FromArgb(
int.Parse((_StartColor.Substring(0, 2)), System.Globalization.NumberStyles.HexNumber),
int.Parse((_StartColor.Substring(2, 2)), System.Globalization.NumberStyles.HexNumber),
int.Parse((_StartColor.Substring(4, 2)), System.Globalization.NumberStyles.HexNumber));
}

if (_EndColor.ToUpper().StartsWith("T"))
{
m_Color2 = Color.Transparent;
}
else
{
m_Color2 = Color.FromArgb(
int.Parse((_EndColor.Substring(0, 2)), System.Globalization.NumberStyles.HexNumber),
int.Parse((_EndColor.Substring(2, 2)), System.Globalization.NumberStyles.HexNumber),
int.Parse((_EndColor.Substring(4, 2)), System.Globalization.NumberStyles.HexNumber));
}



// GO!
sMessage = "determining size";
Bitmap bmpGradient = new Bitmap(lWidth, lHeight);
Rectangle m_BrushSize = new Rectangle(0, 0, lWidth, lHeight);
Graphics grBitmap = Graphics.FromImage(bmpGradient);
sMessage = "creating gradient brush";
LinearGradientBrush myLinearGradientBrush = new LinearGradientBrush(m_BrushSize, m_Color1, m_Color2, myGradientMode);

if ((m_Focus>0) || (m_Scale>0))
{
myLinearGradientBrush.SetSigmaBellShape(m_Focus, m_Scale);
}

sMessage = "filling rectangle";
grBitmap.FillRectangle(myLinearGradientBrush, 0, 0, lWidth, lHeight);
sMessage = "saving image to response stream";
MemoryStream io = new MemoryStream();
bmpGradient.Save(io, myFormat);
Response.BinaryWrite(io.GetBuffer());
}
catch (System.Exception ex)
{
Bitmap bmpGradient = new Bitmap(600, 100);
Rectangle m_BrushSize = new Rectangle(0, 0, 600, 100);
Graphics grBitmap = Graphics.FromImage(bmpGradient);
LinearGradientBrush myLinearGradientBrush = new LinearGradientBrush(m_BrushSize, Color.FromArgb(255, 255, 0, 0), Color.FromArgb(255, 0, 0, 0), LinearGradientMode.Vertical);
grBitmap.FillRectangle(myLinearGradientBrush, 0, 0, 600, 100);
grBitmap.DrawString("ERROR", new System.Drawing.Font("Arial", 12, System.Drawing.FontStyle.Italic), System.Drawing.Brushes.White, 10, 12);

}
}
}



'Stephen' on Wed, 25 Jul 2007 19:14:04 GMT, sez:

skraushaar(at)gmail.com



'zeta clear' on Sat, 16 Feb 2008 08:26:52 GMT, sez:

geek




name


website (optional)


enter the word:
 

comment (HTML not allowed)


All viewpoints welcome. But the right to delete any post for any reason is reserved. Don't make me do it. Comments may be republished, emailed to your loved ones or printed and used as toilet paper. Who reads this legal bit anyhow?

TimeSnapper is a life analysis system that stores and plays-back your computer use. It makes timesheet recording a breeze, helps you recover lost work and shows you how to sharpen your act.

TimeSnapper won last year's Developer Competition at Larkware.com, and is used by over 10,000 people.

Articles

Coding Koan: the power of one Coding Koan: the power of one
Behavior Driven Development: As Human As Possible Behavior Driven Development: As Human As Possible
What To (Really) Do If You Find Out Your Parents Are Using Vista (redux) What To (Really) Do If You Find Out Your Parents Are Using Vista (redux)
What To Do If You Find Out Your Parents Are Using Vista What To Do If You Find Out Your Parents Are Using Vista
Sample Code From Text-Adventure Game Platforms Sample Code From Text-Adventure Game Platforms
TimeSnapper 3.0 -- an interactive, bubbling cauldron of possibilities TimeSnapper 3.0 -- an interactive, bubbling cauldron of possibilities
The laptop compubody sock The laptop compubody sock
Everything that's bad for you is suddenly good for you! Everything that's bad for you is suddenly good for you!
Everything I know about Code Reviews I learnt from Star Wars (and JCooney) Everything I know about Code Reviews I learnt from Star Wars (and JCooney)
Syntax highlighting of strings Syntax highlighting of strings
Google AppEngine: evil virus or viral evil? Google AppEngine: evil virus or viral evil?
Workflow software: I'm calling the bluff. Workflow software: I'm calling the bluff.

Archives .: secretGeek :: Complete Archives :.
25 steps for building a Micro-ISV 25 steps for building a Micro-ISV
3 minute guides -- babysteps in new technologies: powershell, JSON, watir, F# 3 Minute Guide Series
Top 10 SecretGeek articles Top 10 SecretGeek articles

Downloads

TimeSnapper -- Automated Screenshot Journal TimeSnapper.com    
Version 2.5: with password protection

ShinyPower (help with Powershell) ShinyPower
Now at CodePlex

Next Action NextAction
Managing the top of your mind



[powered by Google] 

Thai Erawan, Brisbane Restaurant, delicious thai food in paddington Thai Erawan, Brisbane Restaurant
World's Simplest Code Generator (html edition) World's Simplest Code Generator
Gradient Maker -- a tool for making background images that blend from one colour to another. Forget photoshop, this is the bomb. Gradient Maker
How to be depressed How to be depressed
You are not inadequate.



Recommended Reading

The Best Software Writing I
The Business Of Software (Eric Sink)


Recommended blogs

Jeff Atwood
Reginald Braithwaite
Joseph Cooney
Phil Haack
Scott Hanselman
Julia Lerman
Joel Pobar
Eric Sink
Joel Spolsky
Des Traynor

Aggregated Links

programming.reddit.com
dzone
dot net kicks

Human Link Machines

interesting finds
a continuous learner's weblog
arjan's world
n links today
new and notable
morning coffee
learning .net
weekly link post
(my del.icio.us account)

LinkedIn profile
 
home .: about .: sign up .: sitemap .: secretGeek RSS .: © Leon Bambrick 2003 .: privacy

home .: about .: sign up .: sitemap .: RSS .: © Leon Bambrick 2003 .: privacy