BillyRayPreachersSon
Programmer
A while ago, I found several resources about client-side dynamic image creation. I recently revisited these resources, and have spent a few minutes coming up with this small demo to illustrate the technique.
Browser support for this method is limited, unfortunately. Opera has no support for this method, IE will only support X-Bitmap creation, and NN has the best support - allowing dynamic creation of full-colour GIF images as well as X-Bitmap images. I didn't try JPG images, although I suspect NN may well support them, too.
Enough waffle... here's the code:
The data for the GIF image is the hex data you'd find if you viewed the image in any hex viewer program, such as WinHex. This is then converted to binary using the hexToBinarty function.
The data for the X-Bitmap image is plain text - this is what you would see if you viewed an X-Bitmap file in a hex viewer.
Incidentally, I found a page that used this technique to great effect - the Wolfenstein 5K game ( )... It's a small JavaScript version of Wolfenstein, will all images created dynamically client-side - in less than 5K. Pretty impressive!
Hope someone finds a use for these techniques.
Dan
Browser support for this method is limited, unfortunately. Opera has no support for this method, IE will only support X-Bitmap creation, and NN has the best support - allowing dynamic creation of full-colour GIF images as well as X-Bitmap images. I didn't try JPG images, although I suspect NN may well support them, too.
Enough waffle... here's the code:
Code:
<html>
<head>
<script language="JavaScript">
<!--
function hexToBinary(hexBytes)
{
var output = '';
for (var loop=0; loop<hexBytes.length; loop+=2) output+=String.fromCharCode(eval('0x'+(hexBytes.substring(loop,loop+2)).toString(16)));
return output;
}
var helloWorldGIF = '';
helloWorldGIF += '47494638396164001400F7000000000008000010000010080018000018080018100021000021100821180029000029180831000031080031';
helloWorldGIF += '10083118083900003910084208004218084A21105208005221105A08005A21106331186342086B4210730800732108732910733918735210';
helloWorldGIF += '8400008442218C00008C42218C52189400009429109C08009C10089C31189C42219C6318A50000A50800A51008A54221A54A21AD0000AD10';
helloWorldGIF += '08AD4A21AD6321AD7B18B54A21B55A29B56B21B56B29BD0000BD0800BD6329BD6B29BD7B21C60000C60800C64221C66331C67329C69C18CE';
helloWorldGIF += '0000CE6B31D60000D60800D63918D65A29D66B31DE0800DE1808DE8429E70000E76331EF0000EF3118EF5229EF7B39EFBD18F73118F75229';
helloWorldGIF += 'F75A29F77B39FF0000FF0800FF2110FF3118FF4A21FF5A29FF7331FF8439FF8442FF9439FFAD31FFBD29FFCE21FFDE18FFEF10FFFF08FFFF';
helloWorldGIF += 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
helloWorldGIF += 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
helloWorldGIF += 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
helloWorldGIF += 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
helloWorldGIF += 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
helloWorldGIF += 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
helloWorldGIF += 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
helloWorldGIF += 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C0000';
helloWorldGIF += '0000640014000008FE00D5081C48B0A0C18308132A5CC8B061C23410234A9C48B1A2C58B18336ADC78118DC78F20438A1C49B2A4C9932853';
helloWorldGIF += '963CC3B2254B002E5BC28C1973E6199B346326B0E2B20880222EAD20C84914A74B9B465D9A59CA742980A64C9F42852AD54CD5A95035D868';
helloWorldGIF += '0AC20088A63634601D7BB569D5B24DCBA85DAB1600DBB56EDFBE8D5B86AEDCB72C36B035F0C300DB0D2CEE0AB6CB962E61B664122B4E0C60';
helloWorldGIF += 'B1E2C689732C008040C7E3CB896B4C5E50C33199270814137940660111C50B9E64DEDC99B18F01A42193C9F1807209D9B23D8F192386B76F';
helloWorldGIF += '00BB7B0B073E6608021CC5110CE14D5C0C711C067A8CE9717CB7EF3106AAECFE20628C880FBBABFE0CD88D638074EAD2C700C8A0E588FADD';
helloWorldGIF += 'C697436FDEDCB7F030F8F3E307C0BF7F7FFC16AC901F0D14EC971F00F83D10437E3014A85F1816D0801F025184110502F8D18081166128C8';
helloWorldGIF += 'A083002CC1611808422821872B9448E283FA81E1E28B2E0200E38B32823140162F5231408C34BA18001539063023182B7800861011B898C5';
helloWorldGIF += '044264E1C10A3102E92215428251238F364A090615575E39E4176086092600628649E617FEF537A6996B8A79A6984A38F085072784798207';
helloWorldGIF += '5F38A0449B6CA2E9269F7CBE59E6175E146A68A1001C6A68A25E147085A2882E5AA80053183A8500905E41E90195163A4501971A4AA9A598';
helloWorldGIF += '7AC168A45E0CD0A917579C7A2AA4FE5DC42A6BAC00CC2A6BAD5D5CF082AC4E2040EBADB14AB06BAC2944606BAC15702081AD12705081ACC2';
helloWorldGIF += 'CA5AECAFC0E69A82AC33E0DA85B6C772E1EDB7DE0200EEB7E2729144013C98DB800BE192EB2D0FE872C10301E98ECBC50801A430EE0B018C';
helloWorldGIF += 'F02DBCE9CE5B6FB9ED9A7BC00C5C045100C1F682BB85140F7301B114003C1C31C415432C8302001030C2C4196F11720B0700A0400B164F2C';
helloWorldGIF += 'B111014091F2165004608414126F41B2C928639C72C83B40D0B10921675C33CD104361F4D14827ADF4D24C37EDF4D35047DDB411481861F5';
helloWorldGIF += 'D55867ADB5D5556FEDF5D760872DF6D857EF60F60E40989D36DA6AB7CDF6DB67AF2DB7DB73BF5DF7DD74E76DB73BDE78BFDDC2DF2D98F0B7';
helloWorldGIF += 'E0810F6E78E188034EF8E287338EB8E390372EF9E393478E7808217080F9E69C77EE39E69A7F2EFAE8A4976EFAE99B0704003B';
helloWorldGIF = hexToBinary(helloWorldGIF);
var helloWorldXBM = '';
helloWorldXBM += '#define image_width 100\n';
helloWorldXBM += '#define image_height 20\n';
helloWorldXBM += 'static char image_bits[] = { ';
helloWorldXBM += '0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,';
helloWorldXBM += '0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x01,0x01,0x20,0x01,';
helloWorldXBM += '0x80,0x40,0x20,0x00,0x20,0x40,0x04,0xf0,0x00,0x01,0x01,0x20,0x01,0x80,0xa0,0x20,0x00,0x20,0x40,0x04,0xf0,0x00,';
helloWorldXBM += '0x01,0x01,0x20,0x01,0x00,0xa1,0x10,0x00,0x20,0x40,0x04,0xf0,0x00,0x01,0xe1,0x20,0xe1,0x00,0xa1,0x10,0x0e,0x2d,';
helloWorldXBM += '0x5c,0x04,0xf0,0x00,0x01,0x11,0x21,0x11,0x01,0x11,0x11,0x11,0x23,0x62,0x04,0xf0,0x00,0xff,0x09,0x22,0x09,0x02,';
helloWorldXBM += '0x11,0x91,0x20,0x21,0x41,0x04,0xf0,0x00,0x01,0x09,0x22,0x09,0x02,0x12,0x89,0x20,0x21,0x41,0x04,0xf0,0x00,0x01,';
helloWorldXBM += '0xf9,0x23,0x09,0x02,0x0a,0x8a,0x20,0x21,0x41,0x04,0xf0,0x00,0x01,0x09,0x20,0x09,0x02,0x0a,0x8a,0x20,0x21,0x41,';
helloWorldXBM += '0x04,0xf0,0x00,0x01,0x09,0x22,0x09,0x02,0x0a,0x8a,0x20,0x21,0x41,0x04,0xf0,0x00,0x01,0x11,0x21,0x11,0x01,0x04,';
helloWorldXBM += '0x04,0x11,0x21,0x62,0x00,0xf0,0x00,0x01,0xe1,0x20,0xe1,0x00,0x04,0x04,0x0e,0x21,0x5c,0x04,0xf0,0x00,0x00,0x00,';
helloWorldXBM += '0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,';
helloWorldXBM += '0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,';
helloWorldXBM += '0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0';
helloWorldXBM += ' };';
//-->
</script>
</head>
<body>
GIF:<img src="javascript:helloWorldGIF;" width="100" height="20"><br><br>
XBitmap: <img src="javascript:helloWorldXBM;" width="100" height="20">
</body>
</html>
The data for the GIF image is the hex data you'd find if you viewed the image in any hex viewer program, such as WinHex. This is then converted to binary using the hexToBinarty function.
The data for the X-Bitmap image is plain text - this is what you would see if you viewed an X-Bitmap file in a hex viewer.
Incidentally, I found a page that used this technique to great effect - the Wolfenstein 5K game ( )... It's a small JavaScript version of Wolfenstein, will all images created dynamically client-side - in less than 5K. Pretty impressive!
Hope someone finds a use for these techniques.
Dan