Announcing PhotoDemon 5.0 – Everything is Faster, Everything is Better

Summary

PhotoDemon v5.0 is now available. It’s the biggest update PhotoDemon has seen in years, and it’s awesome. Download it here.

PhotoDemon 5.0 boasts a ton of improvements – both on the surface and under the hood.

New Feature: All-New Image Subsystem

In version 5.0, the way PhotoDemon stores and processes image data has been rewritten from scratch. What does this mean for you?

  • Filters, effects, and all tools are faster than version 4.4.
  • The software uses roughly half the RAM of previous versions.
  • No more upper limit on image sizes. Huge photos (30+ megapixel) should work just fine on any modern PC. The only limiting factor is the amount of RAM (actual and virtual) available on your system.
  • Much faster batch conversions. As an example of how much better version 5.0 is: I ran two identical batch conversions of 138 wedding photos (10 megapixels each, 3872×2592 pixels). The batch conversion was simple – load each image, then save it in another folder at a different JPEG quality. PhotoDemon 4.4 performed the conversion in 2 minutes 21 seconds. PhotoDemon 5.0 does it in 1 minute 11 seconds.
  • Much better OSX and Linux compatibility via Wine. (Wine v1.4 or later is required.)

This sole feature was the largest update PhotoDemon has seen in the past five years. As a teaser, the new subsystem is also compatible with selections and layers, which may make an appearance in a future update…

New Feature: Alpha-Channel (Transparency) Support

For the first time in the history of the program, PhotoDemon now provides proper transparency support. When images with an alpha-channel are loaded, PhotoDemon will automatically maintain the transparency data for the life of the image. When the image is saved to file, the alpha-channel is added back in, allowing you to do any amount of edits to images without harming the underlying alpha data.

Transformations like resizing and rotating also preserve the alpha channel. (Again, this was a prerequisite to features like layers… see a pattern here?)

New Feature: Redesigned Interface

Every menu item in PhotoDemon now has a descriptive icon, and menus have been reorganized according to improved design rules. No menu is more than two layers deep, and new accelerators (hotkeys) have been added to popular features.

The redesigned Color menu

The left-hand bar has been updated once again. Per feedback from users, a dedicated Close and Save As button has been added, along with descriptive text for each button. Tool-tips have also been added to each button. (Thanks to Robert Rayment for the suggestion!) Finally, the zoom box has been rebuilt with a new, more useful set of zoom values.

New left-hand bar in 5.0, including descriptive tool-tips.

All preview boxes have been enlarged on tool, filter, and effect windows. Text has also been enlarged to improve readability. PhotoDemon was originally designed to run on 800×600 resolutions (that was a concern in 2001!) but there’s no need for it to remain so compact in 2012.

The old and new edge detection tools
The old and new Custom Filter tools

Finally, a new View menu has been added to provide compatibility with other popular photo editors. The new menu is a great place to discover all the useful hotkeys (also called “accelerators”) for popular zoom functions. The key listed on the right-hand side of a menu item can be used as a shortcut to that menu – so pressing the “+” key will zoom in, the “-” key will zoom out, and the “0” key will instantly fit the entire image on the screen.

The new View menu

New Feature: All-New Image Load/Save Engine

PhotoDemon 5.0 uses a completely new system for getting images into – and out of – the program. As you may know, the program relies on an outside library called FreeImage for supporting non-standard image formats like Photoshop files (PSD), Macintosh PICT files (PICT), DirectDraw surfaces (DDS), and more.

FreeImage is an excellent tool, but its implementation in past versions of PhotoDemon was very rudimentary. PhotoDemon relied on FreeImage to do its own image file type detection, configure each image type properly, and prepare it for use within the program. While it was pretty good at guessing these parameters, it was not foolproof, and odd color-depths, transparencies, and mismatched file extensions could result in failed image loads or even program crashes.

So for version 5.0, the FreeImage interface was rewritten from the ground up. When images are loaded, a fallback system is used to identify the file format – first the file header is compared against a database of known filetypes. That works for 95+% of files. If for some reason a header cannot be found (which is the case with some formats, including outliers like CUT, MNG, PCD, TGA and WBMP), the image’s file extension is then analyzed. If that fails, PhotoDemon will attempt to blindly load bitmap data and hope for the best. And, if even that fails, PhotoDemon will give the image one final try by passing control off to the Windows’ GDI+ system and seeing if it can decipher the file.

This should make PhotoDemon as robust as possible when loading images. (Thanks to Herman Liu for much testing and help with the new image import implementation!) The full list of file formats supported by PhotoDemon now includes:

Importing:

  • BMP – Windows Bitmap
  • DDS – DirectDraw Surface
  • GIF – Compuserve
  • ICO – Windows Icon
  • IFF – Amiga Interchange Format
  • JNG – JPEG Network Graphics
  • JPG/JPEG – Joint Photographic Experts Group
  • KOA/KOALA – Commodore 64
  • LBM – Deluxe Paint
  • MNG – Multiple Network Graphics
  • PBM – Portable Bitmap
  • PCD – Kodak PhotoCD
  • PCX – Zsoft Paintbrush (uncompressed only)
  • PDI – PhotoDemon Image (the program’s native format)
  • PGM – Portable Greymap
  • PIC/PICT – Macintosh Picture
  • PNG – Portable Network Graphic
  • PPM – Portable Pixmap
  • PSD – Adobe Photoshop
  • RAS – Sun Raster File
  • SGI/RGB/BW – Silicon Graphics Image
  • TGA – Truevision Targa
  • TIF/TIFF – Tagged Image File Format
  • WBMP – Wireless Bitmap

Exporting:

  • BMP – Windows Bitmap
  • GIF – Graphics Interchange Format
  • JPG – Joint Photographic Experts Group
  • PDI – PhotoDemon Image (the program’s native format)
  • PNG – Portable Network Graphic
  • PPM – Portable Pixel Map
  • TGA – Truevision Targa
  • TIFF – Tagged Image File Format

New Feature: Color Temperature Tool

A full discussion of color temperature and how it works is available at this Wikipedia article, but a simple description is: color temperature allows you to retroactively adjust the lighting of a photograph. It’s a powerful way to change the mood of a photo, or to adjust lighting to reflect how you remember a scene – versus what the camera actually caught.

The all-new Color Temperature tool. To my knowledge, no other free photo editor provides a tool like this.

I’m quite proud of this tool, in part because it took a ridiculous amount of work to build. Other free photo editors like GIMP and Paint.NET lack anything like this, so short of Photoshop, PhotoDemon is one of the only software programs to provide such a feature.

The image below – a promotional poster for the HBO series True Blood – nicely demonstrates the potential of color temperature adjustments. On the left is the original shot; on the right, a color temperature adjustment using PhotoDemon. In one click, a nighttime scene can been recast in daylight.

Color temperature adjustment in action.

New Feature: Black and White (1-bit) Conversion

PhotoDemon already possesses a powerful grayscale engine, with more conversion options than any other tool on the market. But what if you want to literally convert an image to black and white – as in just black and just white?

Now you can, thanks to a revamped black-and-white tool.

The new black-and-white tool, rewritten from scratch for 5.0.

The new tool operates hand-in-hand with a flexible, powerful dithering engine. The new engine design allows for any combination of dithering and threshold, and if you’d like, you can also have PhotoDemon estimate an ideal threshold value for a given image. (An ideal threshold is one that leads to an image that’s roughly 50% black and 50% white.)

A comprehensive assortment of dithering algorithms is provided, including: Bayer 4×4 and 8×8, False (fast) Floyd-Steinberg, Genuine Floyd-Steinberg, Jarvis/Judice/Ninke, Stucki, Burkes, Sierra-3, Two-Row Sierra, Sierra Lite, and my personal favorite – Bill Atkinson’s classic Macintosh algorithm, which featured prominently in the original Apple Macintosh. Images treated with this algorithm evoke a certain nostalgia for anyone old enough to remember that era of computing.

Atkinson dithering, as applied to a screen capture from a Warehouse 13 episode.

New Feature: Tile Tool

Have you ever needed to tile an image? There are a lot of ways to do it. Most involve copying-and-pasting an image over and over again, then manually arranging those copies into a grid.

I hate tedious tasks like that. So PhotoDemon has a new tool that makes tiling a trivial operation.

The new Tile tool.

You can tile according to three rules: the current screen size (automatically detected), a set size in pixels, or a set number of tiles. The tool will automatically convert between each system for you, and it will let you know the size of the final image in both tiles and pixels.

Other new features and updates in version 5.0

Other updates in v5.0 include:

  • New “Duplicate Image” tool. Perfect for making a working copy of an image without fear of overwriting the original. (Thanks to Achmad Junus for the suggestion!)
  • Drag-and-Drop compatibility. Drag images from your desktop or file manager onto PhotoDemon, and it will open them all automatically. (Thanks to Kroc of camendesign.com for the suggestion!)
  • Auto-Enhance overhaul. All four auto-enhance tools (contrast, highlights, midtones, shadows) have been rewritten from scratch using completely new algorithms. I think you’ll find them way more useful than the old tools.
  • Improved mosaic tool. Faster, higher quality, and mosaics can now be as large as the image or as tiny as one pixel in either dimension.
  • Improved handling of edge pixels for all convolution filters (blur, soften, sharpen, etc)
  • Improved manual color reduction algorithms (faster and higher quality)
  • New histogram equalization form. Equalize any combination of color channels (red, green, blue) and luminance with real-time previews.
  • DPI-aware images mean no more distortion at 120dpi – a big improvement for people using “large font” settings.
  • Fixes for users of the “Classic Theme” in modern versions of Windows. Your menus should look much better in this release.
  • Improved bug reporting system and online form to match.
  • Tons of miscellaneous bug fixes, tweaks, and optimizations. For a full list of changes, visit https://github.com/tannerhelland/PhotoDemon/commits/master

In Conclusion…

I hope you enjoy the many improvements in version 5.0. As always, feel free to contact me with any feedback you might have.

Announcing PhotoDemon 4.4 – Now With Update Notifications, Improved Histogram, and More

Summary

PhotoDemon v4.4 is now available. It has a lot of cool new features. Download it here.

New Feature: Update Notifications

The most important update in version 4.4 is the addition of an automatic update notifier.

PhotoDemon's new update notifier
PhotoDemon’s new update notifier.

By default, PhotoDemon will check for updates whenever the software is run. Automatic update checks can be disabled from the Edit -> Preferences menu. You can also manually check for updates by going to Help -> Check for Updates.

I’m not sold on the layout of the update notification form – particularly the center alignment of the version numbers, which looks off due to the white space on the right-hand side – so its appearance may change in future versions, but at least this first draft conveys all the essential information.

Finally, note that this is merely an update notifier, not an automatic updater – clicking the “Yes” button will only open the PhotoDemon download page in your browser. It will not download the update for you, and it will not overwrite your current copy of the software. This is my preferred behavior for portable applications, but I am open to suggestions for better methods.

New Feature: Helpful Undo/Redo Text

The left-hand bar in v4.4 has been redesigned from version 4.3:

Comparison of v4.3 and v4.4 left-hand bar
v4.3 is on the left, v4.4 is on the right

The new, more compact version is in preparation for adding additional tools to the bottom section of the left-hand bar. It was also done as part of the new “friendly text” version of the Undo/Redo buttons:

new Undo/Redo interface
PhotoDemon’s helpful new Undo/Redo text.

I tried displaying the full text of the Undo/Redo action in the Undo/Redo buttons themselves, but as some of the descriptions are rather long, the button text would get pushed onto multiple lines (or off the button entirely!) making them look terrible. So the current implementation is: hover over the Undo/Redo button to see what action will be performed. As you can see, the Edit menu also contains a full-text description of Undo/Redo behavior.

Redesigned Histogram

With version 4.4, I don’t think it’s biased to say that PhotoDemon provides the best image histogram tool in the business:

PhotoDemon 4.4's redesigned histogram
PhotoDemon 4.4’s redesigned histogram

Individual channels can now be hidden or displayed in any combination. (The histogram will automatically adjust its maximum and minimum values accordingly.) This is useful for comparing just two color channels, for example, or comparing a single color channel against luminance.

The histogram now provides a “use smooth lines” option. This enables two features: antialiased lines (which VB does not do natively, so it’s a custom implementation), and cubic spline interpolation. Here’s an example of the aesthetic difference this makes:

Comparison of histogram render methods
Makes a difference, doesn’t it?

The new histogram interface provides a logarithmic rendering option. Images that are very dark or very bright will blow out the histogram at one end or the other, making it very difficult to see what’s happening in those ranges. Take the histogram of this beautiful FF7 fan art from pixiv.net user マップ, for example:

Image in need of a logarithmic histogram

Logarithmic histogram in action

Classic features like displaying the values of the histogram level under the cursor are still present, and you can still export the histogram image to an 8-bit PNG, GIF, or BMP file.

Finally, as of version 4.4 PhotoDemon’s histogram window is now non-modal. This means that you can leave the histogram window open while loading/saving/manipulating images, and the window will automatically refresh itself when necessary. Perform a filter or color operation and the histogram will update to reflect those changes; Undo a previous action and it will also update, making it very useful for comparing the effects of various filters.

As part of these updates, the histogram code has been newly refactored and optimized, so it’s fast and extremely low-resource, even when left open during image operations. All histogram data is pre-calculated, so when you change rendering options (such as enabling/disabling channels or switching between logarithmic and regular representation) the new histogram is instantly redrawn without requiring a recalculation of the raw data.

I’m not done with histogram updates, but v4.4 provides a great improvement over v4.3.

Redesigned Grayscale Interface and New Grayscale Algorithms

The grayscale conversion form has been completely redesigned in v4.4:

Redesigned grayscale interface
Special thanks to pixiv user ぴよな*ティア for the image in the preview.

Grayscale conversion was one of the last features to lack an instant-preview option, but no longer – you can now see real-time previews of the various grayscale algorithms.

I have also ported over all seven of the grayscale conversion algorithms from my standalone grayscale project, some of which were not present in PhotoDemon. The full list of available grayscale conversion methods now includes:

  • Averaging
  • ITU standard (adjusting for cone density in the human eyes)
  • Desaturation (HSL color space)
  • Decomposition to maximum or minimum values
  • Single color channel reduction
  • Reduction to specific # of gray shades
  • Reduction to specific # of gray shades with dithering

PhotoDemon defaults to the ITU standard method, which is the best choice for people who have no idea what these various options mean. :) For a full discussion of how these methods work and why some are preferable to others, see my aforementioned in-depth grayscale article.

Finally, the reduce-to-specific-number-of-shades option can now be used to reduce an image to black and white (two shades). Previously it required three shades or more. That said, I still advise using PhotoDemon’s specific “convert to black and white” menu option, which provides more control over 2-color reduction.

Other miscellaneous updates and bugfixes

Other updates in v4.4 include:

  • The system hand cursor is now automatically applied to all clickable objects. This was previously done manually, and because VB isn’t smart about sharing resources, a hand cursor was stored in multiple places throughout the .exe. The new automated feature meant I could remove those references, so the new v4.4 .exe is actually smaller than v4.3, despite including a bunch of additional features. Windows Vista/7 users will also get a much prettier hand icon.
  • Batch conversion now has a more robust error handler. This is in preparation for the addition of an all-new batch conversion wizard, which didn’t make the cut for 4.4 but should be included in 4.5
  • Miscellaneous bug fixes related to save prompting, MDI maximizing, and more. See a full list of updates at PhotoDemon’s commit page on github.

In Conclusion…

I hope you enjoy the changes in version 4.4. As always, feel free to contact me with any feedback you might have.

Seven grayscale conversion algorithms (with pseudocode and VB6 source code)

I have uploaded a great many image processing demonstrations over the years, but today’s project – grayscale conversion techniques – is actually the image processing technique that generates the most email queries for me.  I’m glad to finally have a place to send those queries!

Despite many requests for a grayscale demonstration, I have held off coding anything until I could really present something unique.  I don’t like adding projects to this site that offer nothing novel or interesting, and there are already hundreds of downloads – in every programming language – that demonstrate standard color-to-grayscale conversions.   So rather than add one more “here’s a grayscale algorithm” article, I have spent the past week collecting every known grayscale conversion routine.  To my knowledge, this is the only project on the Internet that presents seven unique grayscale conversion algorithms, and at least two of the algorithms – custom # of grayscale shades with and without dithering – were written from scratch for this very article.

So without further ado, here are seven unique ways to convert a full-color image to grayscale.  (Note: I highly recommend reading the full article so you understand how the various algorithms work and what their purposes might be, but if all you want is the source code, you’ll find it past all the pictures and just above the donation link.)

Grayscale – An Introduction

Black and white (or monochrome) photography dates back to the mid-19th century.  Despite the eventual introduction of color photography, monochromatic photography remains popular.  If anything, the digital revolution has actually increased the popularity of monochromatic photography because any digital camera is capable of taking black-and-white photographs (whereas analog cameras required the use of special monochromatic film).  Monochromatic photography is sometimes considered the “sculpture” variety of photographic art.  It tends to abstract the subject, allowing the photographer to focus on form and interpretation instead of simply reproducing reality.

Because the terminology black-and-white is imprecise – black-and-white photography actually consists of many shades of gray – this article will refer to such images as grayscale.

Several other technical terms will be used throughout my explanations.  The first is color space.  A color space is a way to visualize a shape or object that represents all available colors.  Different ways of representing color lead to different color spaces.  The RGB color space is represented as a cube, HSL can be a cylinder, cone, or bicone, YIQ and YPbPr have more abstract shapes.  This article will primarily reference the RGB and HSL color spaces.

I will also refer frequently to color channels.  Most digital images are comprised of three separate color channels: a red channel, a green channel, and a blue channel.  Layering these channels on top of each other creates a full-color image.  Different color models have different channels (sometimes the channels are colors, sometimes they are other values like lightness or saturation), but this article will primarily focus on RGB channels.

How all grayscale algorithms fundamentally work

All grayscale algorithms utilize the same basic three-step process:

  1. Get the red, green, and blue values of a pixel
  2. Use fancy math to turn those numbers into a single gray value
  3. Replace the original red, green, and blue values with the new gray value

When describing grayscale algorithms, I’m going to focus on step 2 – using math to turn color values into a grayscale value. So, when you see a formula like this:

Gray = (Red + Green + Blue) / 3

Recognize that the actual code to implement such an algorithm looks like:


For Each Pixel in Image {

   Red = Pixel.Red
   Green = Pixel.Green
   Blue = Pixel.Blue

   Gray = (Red + Green + Blue) / 3

   Pixel.Red = Gray
   Pixel.Green = Gray
   Pixel.Blue = Gray

}

On to the algorithms!

Sample Image:

Promo art for The Secret of Monkey Island: Special Edition, ©2009 LucasArts
This bright, colorful promo art for The Secret of Monkey Island: Special Edition will be used to demonstrate each of our seven unique grayscale algorithms.

Method 1 – Averaging (aka “quick and dirty”)

Grayscale - average method
Grayscale image generated from the formula: Average(Red, Green, Blue)

This method is the most boring, so let’s address it first.  “Averaging” is the most common grayscale conversion routine, and it works like this:

Gray = (Red + Green + Blue) / 3

Fast, simple – no wonder this is the go-to grayscale algorithm for rookie programmers.  This formula generates a reasonably nice grayscale equivalent, and its simplicity makes it easy to implement and optimize (look-up tables work quite well).  However, this formula is not without shortcomings – while fast and simple, it does a poor job of representing shades of gray relative to the way humans perceive luminosity (brightness).  For that, we need something a bit more complex.

Method 2 – Correcting for the human eye (sometimes called “luma” or “luminance,” though such terminology isn’t really accurate)

Grayscale generated using values related to cone density in the human eye
Grayscale generated using a formula similar to (Red * 0.3 + Green * 0.59 + Blue * 0.11)

It’s hard to tell a difference between this image and the one above, so let me provide one more example.  In the image below, method #1 or the “average method” covers the top half of the picture, while method #2 covers the bottom half:

Grayscale methods 1 and 2 compared
If you look closely, you can see a horizontal line running across the center of the image. The top half (the average method) is more washed-out than the bottom half. This is especially visible in the middle-left segment of the image, beneath the cheekbone of the background skull.

The difference between the two methods is even more pronounced when flipping between them at full-size, as you can do in the provided source code.  Now might be a good time to download my sample project (available at the bottom of this article) so you can compare the various algorithms side-by-side.

This second algorithm plays off the fact that cone density in the human eye is not uniform across colors.  Humans perceive green more strongly than red, and red more strongly than blue.  This makes sense from an evolutionary biology standpoint – much of the natural world appears in shades of green, so humans have evolved greater sensitivity to green light.  (Note: this is oversimplified, but accurate.)

Because humans do not perceive all colors equally, the “average method” of grayscale conversion is inaccurate.  Instead of treating red, green, and blue light equally, a good grayscale conversion will weight each color based on how the human eye perceives it.  A common formula in image processors (Photoshop, GIMP) is:

Gray = (Red * 0.3 + Green * 0.59 + Blue * 0.11)

Surprising to see such a large difference between the red, green, and blue coefficients, isn’t it?  This formula requires a bit of extra computation, but it results in a more dynamic grayscale image.  Again, downloading the sample program is the best way to appreciate this, so I recommend grabbing the code, experimenting with it, then returning to this article.

It’s worth noting that there is disagreement on the best formula for this type of grayscale conversion.  In my project, I have chosen to go with the original ITU-R recommendation (BT.709, specifically) which is the historical precedent.  This formula, sometimes called Luma, looks like this:

Gray = (Red * 0.2126 + Green * 0.7152 + Blue * 0.0722)

Some modern digital image and video formats use a different recommendation (BT.601), which calls for slightly different coefficients:

Gray = (Red * 0.299 + Green * 0.587 + Blue * 0.114)

A full discussion of which formula is “better” is beyond the scope of this article.  For further reading, I strongly suggest the work of Charles Poynton.  For 99% of programmers, the difference between these two formulas is irrelevant.  Both are perceptually preferable to the “average method” discussed at the top of this article.

Method 3 – Desaturation

Grayscale generated from a Desaturate algorithm
A desaturated image. Desaturating an image takes advantage of the ability to treat the (R, G, B) colorspace as a 3-dimensional cube. Desaturation approximates a luminance value for each pixel by choosing a corresponding point on the neutral axis of the cube.

Next on our list of methods is desaturation.

There are various ways to describe the color of a pixel.  Most programmers use the RGB color model, where each color is described by its red, green, and blue components.  While this is a nice way for a machine to describe color, the RGB color space can be difficult for humans to visualize.  If I tell you, “oh, I just bought a car.  Its color is RGB(122, 0, 255),” you probably can’t picture the color I’m describing.  If, however, I say, “I just bought a car.  It is a bright, vivid shade of violet,” you can probably picture the color in question.  (Note: this is a hypothetical example.  I do not drive a purple car.  :)

For this reason (among others), the HSL color space is sometimes used to describe colors.  HSL stands for hue, saturation, lightnessHue could be considered the name of the color – red, green, orange, yellow, etc.  Mathematically, hue is described as an angular dimension on the color wheel (range [0,360]), where pure red occurs at 0°, pure green at 120°, pure blue at 240°, then back to pure red at 360°.  Saturation describes how vivid a color is; a very vivid color has full saturation, while gray has no saturation.  Lightness describes the brightness of a color; white has full lightness, while black has zero lightness.

Desaturating an image works by converting an RGB triplet to an HSL triplet, then forcing the saturation to zero. Basically, this takes a color and converts it to its least-saturated variant.  The mathematics of this conversion are more complex than this article warrants, so I’ll simply provide the shortcut calculation.  A pixel can be desaturated by finding the midpoint between the maximum of (R, G, B) and the minimum of (R, G, B), like so:

Gray = ( Max(Red, Green, Blue) + Min(Red, Green, Blue) ) / 2

In terms of the RGB color space, desaturation forces each pixel to a point along the neutral axis running from (0, 0, 0) to (255, 255, 255).  If that makes no sense, take a moment to read this wikipedia article about the RGB color space.

Desaturation results in a flatter, softer grayscale image.  If you compare this desaturated sample to the human-eye-corrected sample (Method #2), you should notice a difference in the contrast of the image.  Method #2 seems more like an Ansel Adams photograph, while desaturation looks like the kind of grayscale photo you might take with a cheap point-and-shoot camera.  Of the three methods discussed thus far, desaturation results in the flattest (least contrast) and darkest overall image.

Method 4 – Decomposition (think of it as de-composition, e.g. not the biological process!)

Decomposition - Max Values
Decomposition using maximum values
Decomposition - Minimum Values
Decomposition using minimum values

Decomposing an image (sounds gross, doesn’t it?) could be considered a simpler form of desaturation.  To decompose an image, we force each pixel to the highest (maximum) or lowest (minimum) of its red, green, and blue values.  Note that this is done on a per-pixel basis – so if we are performing a maximum decompose and pixel #1 is RGB(255, 0, 0) while pixel #2 is RGB(0, 0, 64), we will set pixel #1 to 255 and pixel #2 to 64.  Decomposition only cares about which color value is highest or lowest – not which channel it comes from.

Maximum decomposition:

Gray = Max(Red, Green, Blue)

Minimum decomposition:

Gray = Min(Red, Green, Blue)

As you can imagine, a maximum decomposition provides a brighter grayscale image, while a minimum decomposition provides a darker one.

This method of grayscale reduction is typically used for artistic effect.

Method 5 – Single color channel

Grayscale - red channel only
Grayscale generated by using only red channel values.
Grayscale - green channel only
Grayscale generated by using only green channel values.
Grayscale - blue channel only
Grayscale generated by using only blue channel values.

Finally, we reach the fastest computational method for grayscale reduction – using data from a single color channel.  Unlike all the methods mentioned so far, this method requires no calcuations.  All it does is pick a single channel and make that the grayscale value, as in:

Gray = Red

…or:

Gray = Green

…or:

Gray = Blue

Believe it or not, this shitty algorithm is the one most digital cameras use for taking “grayscale” photos.  CCDs in digital cameras are comprised of a grid of red, green, and blue sensors, and rather than perform the necessary math to convert RGB values to gray ones, they simply grab a single channel (green, for the reasons mentioned in Method #2 – human eye correction) and call that the grayscale one.  For this reason, most photographers recommend against using your camera’s built-in grayscale option.  Instead, shoot everything in color and then perform the grayscale conversion later, using whatever method leads to the best result.

It is difficult to predict the results of this method of grayscale conversion.  As such, it is usually reserved for artistic effect.

Method 6 – Custom # of gray shades

Grayscale using only 4 shades
Grayscale using only 4 shades - black, dark gray, light gray, and white

Now it’s time for the fun algorithms.  Method #6, which I wrote from scratch for this project, allows the user to specify how many shades of gray the resulting image will use.  Any value between 2 and 256 is accepted; 2 results in a black-and-white image, while 256 gives you an image identical to Method #1 above.  This project only uses 8-bit color channels, but for 16 or 24-bit grayscale images (and their resulting 65,536 and 16,777,216 maximums) this code would work just fine.

The algorithm works by selecting X # of gray values, equally spread (inclusively) between zero luminance – black – and full luminance – white.  The above image uses four shades of gray.  Here is another example, using sixteen shades of gray:

Grayscale using 16 shades of gray
In this image, we use 16 shades of gray spanning from black to white

This grayscale algorithm is a bit more complex. It looks something like:


ConversionFactor = 255 / (NumberOfShades - 1)
AverageValue = (Red + Green + Blue) / 3
Gray = Integer((AverageValue / ConversionFactor) + 0.5) * ConversionFactor

Notes:
-NumberOfShades is a value between 2 and 256
-technically, any grayscale algorithm could be used to calculate AverageValue; it simply provides
 an initial gray value estimate
-the "+ 0.5" addition is an optional parameter that imitates rounding the value of an integer
 conversion; YMMV depending on which programming language you use, as some round automatically

I enjoy the artistic possibilities of this algorithm.  The attached source code renders all grayscale images in real-time, so for a better understanding of this algorithm, load up the sample code and rapidly scroll between different numbers of gray shades.

Method 7 - Custom # of gray shades with dithering (in this example, horizontal error-diffusion dithering)

Grayscale - four shades, dithered
This image also uses only four shades of gray (black, dark gray, light gray, white), but it adds full error-diffusion dithering support

Our final algorithm is perhaps the strangest one of all.  Like the previous method, it allows the user to specify any value in the [2,256] range, and the algorithm will automatically calculate the best spread of grayscale values for that range.  However, this algorithm also adds full dithering support.

What is dithering, you ask?  In image processing, dithering uses optical illusions to make an image look more colorful than than it actually is.  Dithering algorithms work by interspersing whatever colors are available into new patterns - ordered or random - that fool the human eye into perceiving more colors than are actually present.  If that makes no sense, take a look at this gallery of dithered images.

There are many different dithering algorithms.  The one I provide is one of the simpler error-diffusion mechanisms: a one-dimensional diffusion that bleeds color conversion errors from left to right.

If you look at the image above, you'll notice that only four colors are present - black, dark gray, light gray, and white - but because these colors are mixed together, from a distance this image looks much sharper than the four-color non-dithered image under Method #6.  Here is a side-by-side comparison:

Side-by-side of dithered and non-dithered 4-color grayscale images
The left side of the image is a 4-shade non-dithered image; the right side is a 4-shade image WITH dithering

When few colors are available, dithering preserves more nuances than a non-dithered image, but the trade-off is a "dirty," speckled look.  Some dithering algorithms are better than others; the one I've used falls somewhere in the middle, which is why I selected it.

As a final example, here is a 16-color grayscale image with full dithering, followed by a side-by-side comparison with the non-dithered version:

Grayscale image, 16 shades, dithered
Hard to believe only 16 shades of gray are used in this image, isn't it?
Grayscale, 16 shades, dithered vs non-dithered
As the number of shades of gray in an image increases, dithering artifacts become less and less noticeable. Can you tell which side of the image is dithered and which is not?

Because the code for this algorithm is fairly complex, I'm going to refer you to the download for details. Simply open the Grayscale.frm file in your text editor of choice, then find the drawGrayscaleCustomShadesDithered sub. It has all the gory details, with comments.

Conclusion

If you're reading this from a slow Internet connection, I apologize for the image-heavy nature of this article.  Unfortunately, the only way to really demonstrate all these grayscale techniques is by showing many examples!

The source code for this project, like all image processing code on this site, runs in real-time.  The GUI is simple and streamlined, automatically hiding and displaying relevant user-adjustable options as you click through the various algorithms:

GUI of the provided source code
GUI of the provided source code. The program also allows you to load your own images.

Each algorithm is provided as a stand-alone method, accepting a source and destination picturebox as parameters.  I designed it this way so you can grab whatever algorithms interest you and drop them straight into an existing project, without need for modification.

Comments and suggestions are welcome.  If you know of any interesting grayscale conversion algorithms I might have missed, please let me know.

(Fun fact: want to convert a grayscale image back to color?  If so, check out my real-time image colorization project.)

 

DISCLAIMER: These download files are regularly scanned to ensure they remain free from malicious content. Unfortunately, some virus scanners will flag these .zip files as suspicious simply because they contain source code and/or executable files. I have submitted my projects to a number of companies in an attempt to rectify these false-positives. Some have been cooperative. Others have not. If your virus scanner alerts you regarding these files, please allow the file to be submitted for further analysis (if your program allows for that). This should help ensure that any false-positive warnings gradually disappear for all users.

This site - and its many free downloads - are 100% funded by donations. Please consider a small contribution to fund server costs and to help me support my family. Even $1.00 helps. Thank you!