Home Articles FAQs XREF Games Software Instant Books BBS About FOLDOC RFCs Feedback Sitemap

Q955 Can I manipulate images a pixel at a time?

You are here: irt.org | FAQ | JavaScript | Image | Q955 [ previous next ]

JavaScript 1.0 and 1.1 has no ability to support byte 0 (null) within a string.

Therefore you cannot 'create' images that require \0, even if they can be specified using ascii characters. The only images that you can create are XBM images which are only black or white.

Here is an example of an XBM image. It script creates a one pixel by one pixel XBM image, which it then uses to inform you of the size of the document.

<body onLoad="init()">

<script language="JavaScript"><!--
var single_pixel_xbm = "#define x_width 1\n#define x_height 1\nstatic char x_bits = {0x00};\n";
function init() { alert("width = " + document.images[0].width + "\n" + "height = " + document.images[0].height); }

<img src="javascript:single_pixel_xbm" width="100%" height="100%">

The following example demonstrates image creating and manipulation:

<script language="JavaScript"><!--
var image1 = '#define x_width 16\n#define x_height 16\nstatic char x_bits[] = {\n' +
' 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};\n';

var image2 = '#define x_width 16\n#define x_height 16\nstatic char x_bits[] = {\n' +
' 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff};\n';


<img name="myImage" src="javascript:image1" width="16" height="16">

<input type="button" onClick="if (document.images) myImage.src='javascript:image1'" value="Show Image 1">
<input type="button" onClick="if (document.images) myImage.src='javascript:image2'" value="Show Image 2">


In JavaScript 1.2, the following can be achieved (tested in JavaScript 1.2 in Netscape Navigator 4.5 on GNU/Linux):

<script language="JavaScript"><!--
gif = 'GIF87a \0\20\0\200\0\0\0\0\0\377\377\377,\0\0\0\0 \0\20'+
      '\0\0\2 \214\217\251\313\355\17\243D\240\326\11\1\236zG\333y\231'+

<img name="myImage" src="javascript:gif" width="32" height="32">

I suspect that the above will still cause older browsers to crash.

If you need to place the image in another window, then rather than using document.open('image/gif'), which causes the browser to crash, use something like:

<script language="JavaScript"><!--
gif = 'GIF87a \0\20\0\200\0\0\0\0\0\377\377\377,\0\0\0\0 \0\20'+
      '\0\0\2 \214\217\251\313\355\17\243D\240\326\11\1\236zG\333y\231'+

windowHandle = window.open('about:blank','windowName','width=100,height=100');
if (!windowHandle.opener)
    windowHandle.opener = self;
windowHandle.document.write('<img name="myImage" src="javascript:opener.gif" width="100" height="100">');

The previous image is created using the following JavaScript to define the image source:

<script language="JavaScript"><!--
gif1 = 'GIF87a \0\20\0\200\0\0\0\0\0\377\377\377,\0\0\0\0 \0\20\0\0\2 \214\217\251\313\355\17\243D\240\326\11\1\236zG\333y\2318\222J\30\232\7\252\236W\13\307\362\274\25\0;';

On the latest browsers this should render as a black number 5 on a white background. The image source was given to me by someone on usenet.

Saving the source of the above image to disk and then loading the image into a hex editor reveals something that looks similar to:

00000000  4749 4638 3761 2000 1000 8000 0000 0000  GIF87a ... .....
00000010  FFFF FF2C 0000 0000 2000 1000 0002 208C  ÿÿÿ,.... .....
00000020  8FA9 CBED 0FA3 44A0 D609 019E 7A47 DB79  ©Ëí. £D Ö.. zGÛy
00000030  9938 924A 189A 07AA 9E57 0BC7 F2BC 1500   8 J. .ª W.ÇòŒ..
00000040  3B0A                                     ;...............

Therefore, one could assume that the hex data that makes up the image is:


Using JavaScript, we can attempt to store this data as a string, and then convert it to the format similar to the one used in the first example.

<script language="JavaScript"><!--
function binary(d) {
    var o = '';
    for (var i=0; i<d.length; i=i+2) o+=String.fromCharCode(eval('0x'+(d.substring(i,i+2)).toString(16)));
    return o;

gif2 = binary('47494638376120001000800000000000FFFFFF2C00000000200010000002208C8FA9CBED0FA344A0D609019E7A47DB799938924A189A07AA9E570BC7F2BC15003B0A');

And then used as:

<img src="javascript:gif2"> or
<img src="javascript:binary('47494638376120001000800000000000ffffff2c00000000200010000002208c8fa9cbed0fa344a0d609019e7a47db799938924a189a07aa9e570bc7f2bc15003b0a')">

Feedback on 'Q955 Can I manipulate images a pixel at a time?'

©2018 Martin Webb