The following code provides a routine for fading out an area of an image.
The routine uses the GDI+ bitmap's Lockbits method to provide fast access to the
image data.
It takes an Image and a Rectangle to fade out as parameters, A Fade Direction which
can be up, down, left or right and a fade type. Currently this is can only
be linear, but alternative fade types could be implemented for example to provide
a circular fade.
This routine is available in the GDIPExtensions unit which is part of GDI+ Controls.
type TFadeDirection = (fdUp, fdDown, fdLeft, fdRight); TFadeType = (ftLinear); EImageProcessError = exception; function FadeOut(Image : TGPBitmap; ARect :TGPRect; Direction : TFadeDirection; FadeType : TFadeType) : boolean; var x,y : integer; bmd : TBitmapData; ImageStart : integer; pixelpos : integer; Pixel : pARGB; AlphaChange : Double; CurrentAlpha, NewAlpha : Cardinal; begin if not assigned(Image) then raise EImageProcessError.create('No Image assigned'); if (Image.GetWidth = 0) or (Image.GetHeight = 0) then raise EImageProcessError.create('Height and width of image must be greater than zero'); if (Arect.Width = 0) or (ARect.Height = 0) then raise EImageProcessError.create('Height and width of Rectangle must be greater than zero'); Image.LockBits(Arect, ImageLockModeWrite, PixelFormat32bppARGB, bmd); assert(bmd.PixelFormat = PixelFormat32bppARGB); ImageStart := integer(bmd.Scan0); for y := 0 to bmd.Height do begin AlphaChange := 1; case FadeType of ftLinear : begin case Direction of fdDown : AlphaChange := 1-(y + 1) / ARect.Height; fdUp : AlphaChange := (y + 1) / ARect.Height; end; end; end; for x := 0 to bmd.Width do begin case FadeType of ftLinear : begin case Direction of fdLeft : AlphaChange := (x + 1) / ARect.Width; fdRight : AlphaChange := 1-(x + 1) / ARect.Width; end; end; end; Pixel := pARGB(ptr(ImageStart + (y * bmd.stride) +(x*4))); CurrentAlpha := (Pixel^ and ALPHA_MASK) shr ALPHA_SHIFT; NewAlpha := trunc(CurrentAlpha * AlphaChange); Pixel^ := (NewAlpha shl ALPHA_SHIFT) or (Pixel^ and not ALPHA_MASK); end; end; Image.UnlockBits(bmd); result := true; end;