Mar 262009
 

I have been quietly impressed with the progress web browsers have been making in recent years towards the goal of supporting a wide variety of applications. The promise of web-apps rivaling traditional desktop applications seems within reach after nigh-15 years of ballyhoo. Most recent browsers have extremely fast Javascript support and highly optimized DOMs, allowing a good level of interaction.

Of course, there a times when moving <div>s around just doesn’t cut the mustard. The canvas tag is not well used but is nothing less than a surface you can draw on using Javascript. It supports all the normal primitives (lines, arcs, fills, etc) and allows (indirect) access to the pixel data. While some people (eg: Project Bespin) are using the canvas tag in to offer extended functionality, I am busy fooling around.

Check out the fruit of my labour – Sketch This Page!.

It’s a Javascript bookmarklet that replaces each <img> element in a page with a same sized <canvas>. It works by copying the image to a temporary canvas, extracting the pixel data for some hacky post-processing, and then blatting the pixel-data onto the final canvas. The Javascript could certainly be better, but it works well enough and I am impressed with the speed.

The biggest flaw is that browsers will not allow Javascript to access the pixel data of images that are loaded from a different domain than the main page. This is a great idea from a security standpoint, but it does limit the usefulness of the bookmarklet. It would be great if Sketch This Page! worked on sites like Flickr, but sadly it is not to be.

For those interested, here is the function that actually dithers the image. I was going for a hatched look with the diagonal lines.

function generateBWDitherImage( src, dst )
{
   var srcContext = src.getContext(“2d”);
   var dstContext = dst.getContext(“2d”);

   var srcImageData = srcContext.getImageData(0, 0, src.width, src.height);
   var dstImageData = dstContext.getImageData(0, 0, dst.width, dst.height);
   
   for (var y = 0; y < dstImageData.height; ++y)
   {
      for (var x = 0; x < dstImageData.width; ++x)
      {
         var index = (dstImageData.width * 4) * y + (x * 4);
         var g = (0.30 * srcImageData.data[index]) +
             (0.59 * srcImageData.data[index+1]) +
             (0.11 * srcImageData.data[index+2]);
         if (g > 200)
         {
            g = 255;
         }
         else if (g > 150)
         {
            if (((y % 6) – x % 6) == 0)
               g = 0;
            else
               g = 255;
         }
         else if (g > 75)
         {
            if (((y % 4) – x % 4) == 0)
               g = 0;
            else
               g = 255;
         }
         else
            g = 0;
         dstImageData.data[index] = g;
         dstImageData.data[index+1] = g;
         dstImageData.data[index+2] = g;
         dstImageData.data[index+3] = 255;
      }
   }

   dstContext.putImageData( dstImageData, 0, 0 );
}


Related posts:

  1. Javascript and Saved Passwords
  2. The HTML5 audio tag
  3. Safari 4 is Pretty Good
  4. The HTML5 Video Tag’s Fatal Flaw
  5. TV Theme Quiz II : The Themes Strike Back

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word