iTunes 11 Style Scroller

Spent a couple of hours seeing if I could recreate the album scroller found in the store view of the latest version of iTunes. Uses CSS3 transforms for animation and some jQuery to handle interaction. Definitely needs tidying up, and probably only works in WebKit and latest browsers for now.

Click Me

Kuwahara Filter in C#

The Kuwahara filter is probably one of those things that you haven’t heard of much, if ever. It’s a noise reduction/blurring technique for images that preserves edges, similar to a median filter. It acts like a box blur, except we take that box around the center pixel and divide that into four smaller boxes (with some overlap since the number of items in the box is usually odd along the x and y axis). These smaller boxes are calculated in the same fashion as the box blur for the average value. While we’re doing that, we’re also performing another step: Finding the variance for the box. We want to know which box has the least amount of variance. The variance can be calculated in a number of ways but the easiest is simply finding the minimum and maximum values (for r, g and b) for a box and subtracting the min from the max. The bit of code below is based on my Visual Basic source used in RasterWave:

public static Bitmap KuwaharaBlur(Bitmap Image, int Size)
    System.Drawing.Bitmap TempBitmap = Image;
    System.Drawing.Bitmap NewBitmap = new System.Drawing.Bitmap(TempBitmap.Width, TempBitmap.Height);
    System.Drawing.Graphics NewGraphics = System.Drawing.Graphics.FromImage(NewBitmap);
    NewGraphics.DrawImage(TempBitmap, new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), new System.Drawing.Rectangle(0, 0, TempBitmap.Width, TempBitmap.Height), System.Drawing.GraphicsUnit.Pixel);
    Random TempRandom = new Random();
    int[] ApetureMinX = { -(Size / 2), 0, -(Size / 2), 0 };
    int[] ApetureMaxX = { 0, (Size / 2), 0, (Size / 2) };
    int[] ApetureMinY = { -(Size / 2), -(Size / 2), 0, 0 };
    int[] ApetureMaxY = { 0, 0, (Size / 2), (Size / 2) };
    for (int x = 0; x < NewBitmap.Width; ++x)
        for (int y = 0; y < NewBitmap.Height; ++y)
            int[] RValues = { 0, 0, 0, 0 };
            int[] GValues = { 0, 0, 0, 0 };
            int[] BValues = { 0, 0, 0, 0 };
            int[] NumPixels = { 0, 0, 0, 0 };
            int[] MaxRValue = { 0, 0, 0, 0 };
            int[] MaxGValue = { 0, 0, 0, 0 };
            int[] MaxBValue = { 0, 0, 0, 0 };
            int[] MinRValue = { 255, 255, 255, 255 };
            int[] MinGValue = { 255, 255, 255, 255 };
            int[] MinBValue = { 255, 255, 255, 255 };
            for (int i = 0; i < 4; ++i)
                for (int x2 = ApetureMinX[i]; x2 < ApetureMaxX[i]; ++x2)
                    int TempX = x + x2;
                    if (TempX >= 0 && TempX < NewBitmap.Width)
                        for (int y2 = ApetureMinY[i]; y2 < ApetureMaxY[i]; ++y2)
                            int TempY = y + y2;
                            if (TempY >= 0 && TempY < NewBitmap.Height)
                                Color TempColor = TempBitmap.GetPixel(TempX, TempY);
                                RValues[i] += TempColor.R;
                                GValues[i] += TempColor.G;
                                BValues[i] += TempColor.B;
                                if (TempColor.R > MaxRValue[i])
                                    MaxRValue[i] = TempColor.R;
                                else if (TempColor.R < MinRValue[i])
                                    MinRValue[i] = TempColor.R;
                                if (TempColor.G > MaxGValue[i])
                                    MaxGValue[i] = TempColor.G;
                                else if (TempColor.G < MinGValue[i])
                                    MinGValue[i] = TempColor.G;
                                if (TempColor.B > MaxBValue[i])
                                    MaxBValue[i] = TempColor.B;
                                else if (TempColor.B < MinBValue[i])
                                    MinBValue[i] = TempColor.B;
            int j = 0;
            int MinDifference = 10000;
            for (int i = 0; i < 4; ++i)
                int CurrentDifference = (MaxRValue[i] - MinRValue[i]) + (MaxGValue[i] - MinGValue[i]) + (MaxBValue[i] - MinBValue[i]);
                if (CurrentDifference < MinDifference && NumPixels[i] > 0)
                    j = i;
                    MinDifference = CurrentDifference;
            Color MeanPixel = Color.FromArgb(RValues[j] / NumPixels[j],
                GValues[j] / NumPixels[j],
                BValues[j] / NumPixels[j]);
            NewBitmap.SetPixel(x, y, MeanPixel);
    return NewBitmap;

The code above takes in an image as well as the size that you want the aperture to be. In turn it gives you a smoothed image. This filter technique is quite different from other blur filters as it produces a lot more stylized look. Hopefully this helps you out in some way.

Craigslist Monitor using Ruby


To add to my ever expanding knowledge base of languages, I decided to spend the last day and a half teaching myself Ruby and this was the result. A script to watch Craigslist for relevant posts so you don’t have to. My first ever Ruby program.

Watching Craigslist can be a time-consuming task. The script automates searching for housing, sales, services, jobs, and gigs, and emails you when it find something that matches your search criteria. It also works across multiple cities, since it’s controlled by the RSS feeds you configure it with.


Instead of sending Craigslist a server-side query, I decided to just get the RSS feed and filter the results on the client-side. There are two advantages of this — server changes don’t break the code and you can watch other feeds in a similar way (e.g. eBay).


Edit the monitor.yml file to your liking. It should look something like this:

include: software, developer, computer, programmer
exclude: freelance, internship, supplement, contract
  port: 587
  user_name: 'a_username'
  password: 'a_password'


clockwork monitor.rb

That’s it. if you want to log the output:

clockwork monitor.rb > monitor.log

Press CTRL+C to exit

Downloads 19 Sep 2014 3 KB

RasterWave 2.4 Release

After months of hard work, RasterWave 2.4 is officially available for download. You can grab it from the program page or use the update feature within RasterWave.

For those upgrading directly from version 2.2, you’re going to notice a lot of improvements! You can find a full write-up here, but for those in a hurry, here is an abbreviated list of what’s available in version 2.4.

  • LAYERS! RasterWave now provides comprehensive layer support, including variable opacity, custom blendmodes, on-canvas moving and resizing, and editing without flattening.
  • Numerous interface improvements, including new slider, radio button, and check box controls created specifically for RasterWave.
  • Many new tools, including straighten, auto-correction, auto-enhancement, split-toning, HDR, colored pencil, glass tiles, stained glass, fragment, Kuwahara filtering, lens flare, sunshine, noise removal (bilateral smoothing), and more.
  • Many improvements to existing tools, including overhauled Curve and Level dialogs, tonal range support when adjusting color balance, completely rewritten comic book, relief, emboss/engrave, edge enhance, find edges, rainbow, fog, and ignite filters, and many smaller tweaks and improvements.
  • New Undo History browser
  • Improved performance program-wide, including Performance options, and significant performance improvements when language translations are active.
  • Much better support for non-English locales, including many bug-fixes for locales that use “,”, as a decimal separator.
  • Improved drag/drop support, including improved support for dragging images from web browsers.
  • Improved status bar, including clickable “resize image” button and “fit image on-screen” button.
  • New Malay and Swedish language support
  • Improved support for using arrow keys to modify various settings
  • New Asynchronous image metadata processing. Images with extensive metatdata now load and save much faster than before.
  • Reduced program startup time, and greatly reduced shutdown time when many images are loaded
  • Improved mousewheel zoom, with zoom now preserving cursor location.
  • Improvements to Content-Aware resizing, including faster performance, symmetrical seam removal, and ESC-to-cancel functionality.
  • Improved image load time, especially for large images and/or complex image formats.

For a full list of this version’s bug-fixes, improvements, and enhancements, please view the What’s New file included with RasterWave.

NOTE: As you might have noticed, no screenshots are available of the program’s features. Don’t worry, I’m in the process of adding these.

Update Status

I’m attempting to upload the backlog of code I have on my harddrive as quickly as I can. I’m also running into issues moving some web applications over to the new server, which is producing some unexpected errors. Please be patient as it will take a little bit of time.

RasterWave 2.4 Beta

RasterWave 2.4 is nearing release. A few minor items still need addressing, and some language files are incomplete, but the core program is 99% ready.

The biggest change in this version is new support for image layers. As part of implementing layers, many program elements were rewritten from scratch, so this development cycle as been an arduous one. Hopefully the improvements have been worth the wait!

For users upgrading from 2.2, here is are all the new features and improvements you’ll find in version 2.4.


  • Each image now supports an unlimited number of layers
  • Layers can be reordered using drag-drop, or navigation buttons
  • Variable opacity and 24 blend modes are supported
  • Layered images can be resized, rotated, flipped and mirrored without flattening the image.
  • A new Layers menu provides all the same options as the Layers toolbox, plus aditional options like Flatten Image, Merge Visible Layers, adding/removing individual layer transparency, and adjusting layer orientation.
  • Layers can be moved around the canvas in real-time using the new “Move” tool.
  • The new “Move” tool also allows you to non-destructively resize layers.
  • When moving and sizing layers, you can simply click the relevant layers in the canvas without using the Layer toolbox.
  • Layered images can be now be saved in RasterWave’s own native format (.RWD, “RasterWave Document”).
  • New layer options are available in the Edit menu, including Cut and Copy From Layer, and Paste as New Layer.

    These live in the new “quick fix” menu on the toolbar (marked by a lightbulb). Non-destructive means that these changes are not permanently applied to the image. If you wish to undo any edit, simply set the slider back to zero, or use the “reset: button on the quick fix panel. This allows you to customize these parameters whenever you like, without harming image quality.


    New slider, radio button, and check box controls have been created specifically for RasterWave. Besides looking prettier, they are also much more usable. The sliders in particular now provide much more feedback than the terrible old scroll bars they replaced.


  • New Fade tool. After applying an action to an image or layer, you can use Edit > Fade to fade the effect after the fact. Blend mode can also be adjusted.
  • New Straighen tool, for more nuanced control than Arbitrary Rotate.
  • New auto correct options for one-click color, contrast, and lighting fixes.
  • New auto-enhance options for color, contrast, and lighting. These provide an easy way to make a photo more dramatic or colorful, without fiddling with a dialog.
  • Split-toning
  • HDR adjustment
  • Colored pencil artistic effect, with four pencil modes.
  • Glass Tiles
  • Stained Glass
  • Fragment
  • Kuwahara filtering
  • Lens Flare
  • Sunshine
  • Bilateral Smoothing (noise removal)

    Many of RasterWave’s existing tools have received performance, quality, and other improvements. Some of the notable updates include:

  • Improved Curves dialog, with new per-channel support and an improved interface (including live display of parameters).
  • Overhauled Levels dialog, including per-channel support, click-to-set color options, and a new best-in-class Auto Levels option.
  • Color Balance now allows you to limit color adjustments by tonal range.
  • Overhauled comic book filter, with new options for ink density and color smoothing.
  • Overhauled Relief filter, with new options for angle, thickness, and relief depth.
  • Overhauled Emboss/Engrave filter, with new options for angle, thickness, and depth.
  • Overhauled Edge Enhance filter, with new options for edge detection mode, direction, and strength.
  • Overhauled Find Edges dialog, with new edge operators and directionality support.
  • Overhauled Rainbow filter, with new options for offset, angle, strength, and saturation boosting.
  • Overhauled Fog filter, with new options for scale, contrast, density, and render quality.
  • Overhauled Ignite filter (formerly Burn), with new options for intensity, flame height, and strength.

    The new Edit > Undo History browser allows you to jump to any point in an image’s past (or future, if you’ve already undone some changes).


    A new Performance Options category allows you to customize how RasterWave handles certain trade-offs — for example, if you’re low on disk space, you might prefer to heavily compress Undo/Redo data, which saves space at a slight performance trade-off. Similiary, if you have an underpowered processor, you may wish to reduce the amount of on-screen effects (drop shadows, etc) in order to improve render performance.


  • Much better drag/drop support, including improved support for dragging images from web browsers.
  • Improved status bar, including a clickable “resize image” button and “fit image on-screen” button.
  • Improved support for using arrow keys to modify various settings.
  • New asynchronous image metadata processing. Images with extensive metadata now load and save much faster than before.
  • Reduced program startup time, and greatly reduced shutdown time if many images were loaded.
  • Improved mousewheel zoom, with zoom now preserving cursor location.
  • New Select > Erase selected area option.
  • Many improvements to Content-Aware resizing, including faster performance, symmetrical seam removal, and ESC-to-cancel functionality.
  • Improved image load time, especially for large images and/or complex formats.

    Barring any major bugs, the official 2.4 release should happen within the next week or so. Automatic update notifications for existing installs will go live at that point.