IRsoft - Software and more by Ingmar Runge

Delphi: GDI+ Web 2.0 Reflection

This code can be used to reflect any image in your existing GDI+ Delphi code "Web 2.0 style". It's also called the Glass Table Effect. Here's an example. As you can see, different from other implementations, it works on all types of backgrounds!

Trilly Tunes 2.0 Screenshot
{
  Target: Graphics handle you want the reflection to be drawn an.
  SourceBMP: Bitmap that the reflection will be created from.
  SrcWidth / SrcHeight: Height/Width of SourceBMP. Set to -1 to determine automatically.
  ReflHeight: Desired height of the reflection.
  BottomCutOff: If there's a shadow or border at the bottom of SourceBMP,
    set BottomCutOff to the number of pixel rows to ignore in the reflection
    (counted from the bottom upwards).
  TargetX, TargetY: Position on Target the reflection will be drawn to.
  StartOpacity: Opacity for the topmost reflection pixel row. between 255 = opaque and 0 = invisible!

  The routine doesn't perform any extensive error checks, so that is you job before calling.

  You may want to make Target associated with a bitmap and keep that bitmap in memory
  instead of redrawing the reflection every time you redraw your canvas.
  That will save a lot of CPU time.
}

procedure DrawReflection(Target: TGPGraphics; SourceBmp: TGPBitmap;
  SrcWidth, SrcHeight, ReflHeight, BottomCutOff, TargetX, TargetY, StartOpacity: Integer);
var
  ReflImg: TGPBitmap;
  x, y, alpha: Integer;
  colorTemp: TGPColor;
begin
  if SrcWidth < 0 then
    SrcWidth := SourceBmp.GetWidth();

  if SrcHeight < 0 then
    SrcHeight := SourceBmp.GetHeight();

  if ReflHeight < 0 then
    ReflHeight := SrcHeight div 3;

  if ReflHeight > SrcHeight then
    ReflHeight := SrcHeight;

  // bitmap that will be turned into the reflection:
  ReflImg := TGPBitmap.Create(SrcWidth, ReflHeight, PixelFormat32bppARGB);

  for y := SrcHeight - 1 downto SrcHeight - ReflHeight do
  begin
    for x := 0 to SrcWidth - 1 do
    begin
      SourceBmp.GetPixel(x, y - BottomCutOff, colorTemp);
      if GetAlpha(colorTemp) <> 0 then
      begin
        alpha := ((y - (SrcHeight - ReflHeight)) * StartOpacity div ReflHeight) - (255 - GetAlpha(colorTemp));
        if alpha > 0 then
        begin
          colorTemp := MakeColor(alpha, GetRed(colorTemp), GetGreen(colorTemp), GetBlue(colorTemp));
          ReflImg.SetPixel(x, SrcHeight - 1 - y, colorTemp);
        end;
      end;
    end;
  end;

  // copy reflection into main image:
  Target.DrawImage(ReflImg, TargetX, TargetY);
  ReflImg.Free();
end;
Parsed in 0.028 seconds, using GeSHi © 2005 Nigel McNie

The code assumes that you added the units GDIPOBJ and GDIPAPI to your uses clause. You can download those units from progdigy.com if don't have them.

Update April 4 2009: Fixed two issues and added a sample application. Download it here.

Example Reflection
Last edited by Ingmar on Saturday, April 4th 2009 12:41:33 CEST