Categories
Delphi

How to Fade out an area of an image in GDI+

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;