Skip to content

Boian’s TBitmap Visualizer and converting to grayscale

Debugger Visualizers introduced in RAD Studio 2010, for both Delphi 2010 and C++Builder 2010, are one of the most interesting new IDE features. On the ITDevCon 2009 Delphi conference in Verona I have met Boian Mitov from Mitov Software, who actually wrote a sample "TBitmap" visualizer for Delphi 2010. Boian has architected lots of VCL components for all kinds of signal processing, including advanced video and audio processing implementation. Very cool and sophisticated stuff demonstrating the power of Delphi:-)

TBitmap Debugger Visualizer for Delphi is installed into the IDE

OK. I have downloaded and installed TBitmap visualizer into the IDE and it would be good to actually debug some code to try it out. So I thought about implementing an algorithm to convert arbitrary bitmaps to grayscale.

Colors in computing are typically represented by the combination of intensity of the main three colors: red, green and blue (RGB). There are also other representations possible, but let’s stick to RGB. The color is considered gray when intensities for all three basic colors are the same. The special cases of gray are: black with zero intensities, and white with maximum possible intensities of all three colors.

One of the most popular color format is 24bit, where each color is represented by one byte, or a value from 0 to 255 range. The additional, fourth byte, is used to store the Alpha channel or - in other words - transparency level.

Few clicks away I have found the description of three algorithms to convert to grayscale as implemented by GIMP: lightness, average and luminosity. All these formulas take R, G and B values of the color and calculate a value in grayscale that can be assigned back to the original R, G and B parts yielding a gray color.

The Lightness method averages the most prominent and least prominent colors: (max(R, G, B) + min(R, G, B)) div 2.

The Average is simple average value of all three colors: (R + G + B) div 3.

The formula for Luminosity is 0.21 R + 0.71 G + 0.07 B. It is a weighted average to account for human perception. We’re more sensitive to green than other colors, so green is weighted most heavily.

That’s a playing field for the TBitmap visualizer. You can see the contents of the bitmap before and after converting an image to a grayscale. You only need to set a breakpoint and select "Show Bitmap" in the debugger local variables "Visualizers" context menu. The visualizer displays the bitmap itself and information about its size, format and the color of a pixel if a mouse hovers on the bitmap.

Here is the actual source code for converting bitmaps to grayscale. I am sure this could be optimized for speed, but it is more for illustration purposes.


unit uBitmapUtils;

interface

uses
  Graphics, Windows;

type
  TColor2Grayscale = (
    c2gLightness,
    c2gAverage,
    c2gLuminosity
  );

procedure ToGray(aBitmap: Graphics.TBitmap; cg: TColor2Grayscale = c2gLuminosity);
function ColorToGray(c: TColor; cg: TColor2Grayscale = c2gLuminosity): TColor;

implementation

uses
  SysUtils, Math;

function Min(const A, B, C: integer): integer;
begin
  Result := Math.Min(A, Math.Min(B,C));
end;

function Max(const A, B, C: integer): integer;
begin
  Result := Math.Max(A, Math.Max(B,C));
end;

function ColorToGray(c: TColor; cg: TColor2Grayscale = c2gLuminosity): TColor;
var R, G, B, X : Integer;
begin
  R := c and $ff;
  G := (c and $ff00) shr 8;
  B := (c and $ff0000) shr 16;

  case cg of
    c2gLightness:
      X := (max(R, G, B) + min(R, G, B)) div 2;

    c2gAverage:
      X := (R + G + B) div 3;

    c2gLuminosity:
      X := round(0.21*R + 0.71*G + 0.07*B);

    else
      raise Exception.Create('Unknown Color2Grayscale value');
  end;

  Result := TColor(RGB(X,X,X));
end;

procedure ToGray(aBitmap: Graphics.TBitmap; cg: TColor2Grayscale = c2gLuminosity);
var i, j: integer;
begin
  if aBitmap <> nil then
  begin
    for i := 0 to aBitmap.Width - 1 do
      for j := 0 to aBitmap.Height - 1 do
        aBitmap.Canvas.Pixels[i,j] := ColorToGray(aBitmap.Canvas.Pixels[i,j], cg);
  end;
end;

end.

The source code of this test app can be downloaded from EDN CodeCentral and Boian Mitov’s "TBitmap" RAD Studio 2010 debugger visualizer can be found here on Mitov Software website.

{ 2 } Comments

  1. Mike | March 29, 2010 at 9:57 am | Permalink

    There are a few more conversions available - e.g. Matlab uses the following
    coefficients:

    Rounded (0.2989, 0.5870, 0.1141)

    to convert RGB to grayscale (and I think they are the same as used in the good old analog television area)

  2. Free Rapidshare Premium Account | January 22, 2011 at 5:11 pm | Permalink

    Thanks :)

{ 1 } Trackback

  1. [...] Paweł Głowacki : Boian’s TBitmap Visualizer and converting to grayscale blogs.embarcadero.com/pawelglowacki/2010/03/29/39019 – view page – cached Delphi Programming Filter tweets [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

Bad Behavior has blocked 2 access attempts in the last 7 days.

Close