Graphic Delphi

Title: Drawing and mixing trasparent bitmaps
Question: Usually, when you make a game, it's very usefull to draw transparent bitmaps (without background). And so, mix bitmaps, (one over another one). This is a simple way to do that.
Answer:
//---------------------------------------------------------------------------
// Author : Digital Survivor [Esteban Rodrguez Nieto | Jos Plano]
// Email : plmad666@gmail.com | jose.plano@gmail.com
// Web site : www.ds-studios.com.ar
//---------------------------------------------------------------------------
{ The following unit draws two bitmaps on a form. One is used as the
background and the second one as the foreground. The foreground bitmap is displayed as a "transparent" bitmap. This shows the two bitmaps mixed, one over another, We need to use the known BitBlt API to do the job. This example is quite fast.}
Unit TranspBMP;
Interface
Uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;
Type

TForm1 = Class (TForm)

Procedure FormCreate (Sender : TObject);
Procedure FormClose (Sender : TObject; Var Action : TCloseAction);

Private { Private declarations }

ImageForeGround : TImage;
ImageBackGround : TImage;
Public { Public declarations }
End;
Procedure DrawTransparentBitmap (Ahdc : HDC; Image : TImage; XStart, YStart : Word);
Var
Form1 : TForm1;
Implementation
{$R *.DFM}
Procedure DrawTransparentBitmap (Ahdc : HDC; Image : TImage; XStart, YStart : Word);
Var
TransparentColor : TColor;
CColor : TColorRef;
BmAndBack, BmAndObject, BmAndMem, BmSave, BmBackOld, BmObjectOld, BmMemOld, BmSaveOld : HBitmap;
HdcMem, HdcBack, HdcObject, HdcTemp, HdcSave : HDC;
PtSize : TPoint;
Begin
// Set the transparent color to be the lower left pixel of the bitmap
TransparentColor := Image.Picture.Bitmap.Canvas.Pixels [0, Image.Height - 1];
TransparentColor := TransparentColor or $02000000;
HdcTemp := CreateCompatibleDC (Ahdc);
SelectObject (HdcTemp, Image.Picture.Bitmap.Handle); // Select the bitmap
// Convert bitmap dimensions from device to logical points
PtSize.X := Image.Width;
PtSize.Y := Image.Height;
DPtoLP (HdcTemp, PtSize, 1); // Convert from device logical points
// Create some DCs to hold temporary data
HdcBack := CreateCompatibleDC (Ahdc);
HdcObject := CreateCompatibleDC (Ahdc);
HdcMem := CreateCompatibleDC (Ahdc);
HdcSave := CreateCompatibleDC (Ahdc);
// Create a bitmap for each DC
BmAndBack := CreateBitmap (PtSize.X, PtSize.Y, 1, 1, NIL);
BmAndObject := CreateBitmap (PtSize.X, PtSize.Y, 1, 1, NIL);

BmAndMem := CreateCompatibleBitmap (Ahdc, PtSize.X, PtSize.Y);
BmSave := CreateCompatibleBitmap (Ahdc, PtSize.X, PtSize.Y);
// Each DC must select a bitmap object to store pixel data
BmBackOld := SelectObject (hdcBack, bmAndBack);
BmObjectOld := SelectObject (hdcObject, bmAndObject);
BmMemOld := SelectObject (hdcMem, bmAndMem);
BmSaveOld := SelectObject (hdcSave, bmSave);
// Set proper mapping mode
SetMapMode (HdcTemp, GetMapMode (Ahdc));
// Save the bitmap sent here, because it will be overwritten
BitBlt (HdcSave, 0, 0, PtSize.X, PtSize.Y, HdcTemp, 0, 0, SrcCopy);
// Set the background color of the source DC to the color contained in the
// parts of the bitmap that should be transparent
CColor := SetBkColor (HdcTemp, TransparentColor);
// Create the object mask for the bitmap by performing a BitBlt()
// from the source bitmap to a monochrome bitmap
BitBlt (HdcObject, 0, 0, PtSize.X, PtSize.Y, HdcTemp, 0, 0, SrcCopy);
// Set the background color of the source DC back to the original color
SetBkColor (HdcTemp, CColor);
// Create the inverse of the object mask
BitBlt (HdcBack, 0, 0, PtSize.X, PtSize.Y, HdcObject, 0, 0, NotSrcCopy);
// Copy the background of the main DC to the destination
BitBlt (HdcMem, 0, 0, PtSize.X, PtSize.Y, Ahdc, XStart, YStart, SrcCopy);
// Mask out the places where the bitmap will be placed
BitBlt (HdcMem, 0, 0, PtSize.X, PtSize.Y, HdcObject, 0, 0, SrcAnd);
// Mask out the transparent colored pixels on the bitmap
BitBlt (HdcTemp, 0, 0, PtSize.X, PtSize.Y, hdcBack, 0, 0, SrcAnd);
// Xor the bitmap with the background on the destination DC
BitBlt (HdcMem, 0, 0, PtSize.X, PtSize.Y, hdcTemp, 0, 0, SrcPaint);
// Copy the destination to the screen
BitBlt (Ahdc, XStart, YStart, PtSize.X, PtSize.Y, HdcMem, 0, 0, SrcCopy);
// Place the original bitmap back into the bitmap sent here
BitBlt (HdcTemp, 0, 0, PtSize.X, PtSize.Y, HdcSave, 0, 0, SrcCopy);
// Delete the memory bitmaps
DeleteObject (SelectObject (HdcBack, BmBackOld));
DeleteObject (SelectObject (HdcObject, BmObjectOld));
DeleteObject (SelectObject (HdcMem, BmMemOld));
DeleteObject (SelectObject (HdcSave, BmSaveOld));
// Delete the memory DCs
DeleteDC (HdcMem);
DeleteDC (HdcBack);
DeleteDC (HdcObject);
DeleteDC (HdcSave);
DeleteDC (HdcTemp);
End;
Procedure TForm1.FormCreate (Sender : TObject);
Begin
// Create image controls for two bitmaps and set their parents
ImageForeGround := TImage.Create (Form1);
ImageForeGround.Parent := Form1;
ImageBackGround := TImage.Create (Form1);
ImageBackGround.Parent := Form1;
// Load images
ImageBackGround.Picture.LoadFromFile ('c:\mad.bmp');
ImageForeGround.Picture.LoadFromFile ('c:\utilman.bmp');
// Set background image size to its bitmap dimensions
With ImageBackGround Do

Begin

Left := 0;
Top := 0;
Width := Picture.Width;
Height := Picture.Height;
End;
// Set the foreground image size centered in the background image
With ImageForeGround Do
Begin
Left := (ImageBackGround.Picture.Width - Picture.Width) Div 2;
Top := (ImageBackGround.Picture.Height - Picture.Height) Div 2;

Width := Picture.Width;
Height := Picture.Height;
End;
// Do not show the transparent bitmap as it will be displayed BitBlt()ed
// by the DrawTransparentBitmap() function
ImageForeGround.Visible := False;
// Draw the tranparent bitmap note how the DC of the foreground is used in
// the function below
DrawTransparentBitmap (ImageBackGround.Picture.Bitmap.Canvas.Handle,
ImageForeGround, ImageForeGround.Left, ImageForeGround.Top);
End;
Procedure TForm1.FormClose (Sender: TObject; Var Action : TCloseAction);
Begin
// Free images
ImageForeGround.Free;
ImageBackGround.Free;
End;
End.