FAQ VCL
Графика

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика

Как рассчитать размеры миниатюры, чтобы вписать ее в заданную область?

var
  Bmp: TBitmap;

// Вычисление множителя для масштабирования картинки (миниатюры)
// SourceWidth, SourceHeight - размеры исходного изображения
// PreviewWidth, PreviewHeight - размеры, в которые изображение нужно вписать
function CalcFactor( SourceWidth, SourceHeight, PreviewWidth, PreviewHeight: Integer ): Double;
begin
  if ( PreviewWidth < SourceWidth ) or ( PreviewHeight < SourceHeight ) then
     Result := Min( PreviewWidth / SourceWidth, PreviewHeight / SourceHeight )
  else
     Result := 1;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Factor: Double;
  NewWidth, NewHeight: Integer; 
begin
   // Допустим в переменной Bmp: TBitmap хранится изображение,
   // для которого нужно вычислить размер его миниатюры
   Factor := CalcFactor( Bmp.Width, Bmp.Height, 100, 100 );
   NewWidth := Round( Factor * Bmp.Width ); // Ширина миниатюры
   NewHeight := Round( Factor * Bmp.Height ); // Высота миниатюры
end;


Как извлечь иконку из файла (.exe, .dll, .cpl и др.) по индексу?

// Способ первый
{$IFDEF UNICODE}
  function PrivateExtractIcons(lpszFile: PChar; nIconIndex, cxIcon, cyIcon: integer; phicon: PHANDLE; piconid: PDWORD; nicon, flags: DWORD): DWORD;
    stdcall ; external 'user32.dll' name 'PrivateExtractIconsW';
{$ELSE}
  function PrivateExtractIcons(lpszFile: PChar; nIconIndex, cxIcon, cyIcon: integer; phicon: PHANDLE; piconid: PDWORD; nicon, flags: DWORD): DWORD;
    stdcall ; external 'user32.dll' name 'PrivateExtractIconsA';
{$ENDIF}

function ExtractIcons( SourceFile: string; IconIndex, cxIcon, cyIcon: Integer;
  TargetFile: string ): Boolean;
var
  hIcon: THandle;
  nIconId: DWORD;
  Icon: TIcon;
begin
   Result := False;
   if PrivateExtractIcons( PWideChar( SourceFile ), IconIndex, cxIcon, cyIcon, @hIcon,
      @nIconId, 1, LR_LOADFROMFILE ) <> 0 then
   try
      Icon := TIcon.Create;
      try
         Icon.Handle := hIcon;
         Icon.SaveToFile( TargetFile );
         Result := True;
      finally
         Icon.Free;
      end;
   finally
      DestroyIcon( hIcon );
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   if ExtractIcons( 'Shell32.dll', 15, 256, 256, 'c:\SavedIcon.ico' ) then
      ShowMessage( 'Иконка сохранена.' );
end;

// Способ второй
uses
  {...,} ShellAPI;

procedure TForm1.Button1Click(Sender: TObject);
begin
   Image1.Picture.Icon.Handle :=
      ExtractIcon(HInstance, PChar('c:\Windows\explorer.exe'), 0);
end;

// Способ третий
uses
  {...,} ShellAPI;

procedure TForm1.Button1Click(Sender: TObject);
const
  FileName = 'c:\Windows\explorer.exe';
var
 Icon: TIcon;
 Icon32, Icon16: HICON;
 i: Integer;
begin
   try
      // Так можно получить количество иконок в файле
      // ExtractIconEx(PChar(FileName), -1, Icon16, Icon32, 0);
      i := 0;
      while Integer(ExtractIconEx(PChar(FileName), i, Icon16, Icon32, 1)) > 0 do
      begin
         Icon := TIcon.Create;
         Icon.Handle := Icon32;
         ImageList1.AddIcon(Icon);
         Icon.Free;
         Inc(i);
      end;
   except
      on e: Exception do
         //
   end;
end;


Как нарисовать диск и окружность со сглаживаниему?

uses
  {...,} Math;

type
  TForm1 = class(TForm)
    Button1: TButton;
    imMain: TImage;
    procedure Button1Click(Sender: TObject);
  private
  public
  end;

implementation

procedure DrawDisk( Bitmap: TBitmap; CenterX, CenterY, Radius, Feather: Single );
// Draw a disk on Bitmap. Bitmap must be a 256 color (pf8bit) palette bitmap,
// and parts outside the disk will get palette index 0, parts inside will get
// palette index 255, and in the antialiased area (feather), the pixels will
// get values inbetween.
// ***Parameters***
// Bitmap:
//   The bitmap to draw on
// CenterX, CenterY:
//   The center of the disk (float precision). Note that [0, 0] would be the
//   center of the first pixel. To draw in the exact middle of a 100x100 bitmap,
//   use CenterX = 49.5 and CenterY = 49.5
// Radius:
//   The radius of the drawn disk in pixels (float precision)
// Feather:
//   The feather area. Use 1 pixel for a 1-pixel antialiased area. Pixel centers
//   outside 'Radius + Feather / 2' become 0, pixel centers inside 'Radius - Feather/2'
//   become 255. Using a value of 0 will yield a bilevel image.
// Copyright (c) 2003 Nils Haeck M.Sc. www.simdesign.nl
var
  x, y: integer;
  LX, RX, LY, RY: integer;
  Fact: integer;
  RPF2, RMF2: single;
  P: PByteArray;
  SqY, SqDist: single;
  sqX: array of single;
begin
   // Determine some helpful values (singles)
   RPF2 := Sqr( Radius + Feather/2 );
   RMF2 := Sqr( Radius - Feather/2 );

   // Determine bounds:
   LX := Max( Floor( CenterX - RPF2 ), 0 );
   RX := Min( Ceil( CenterX + RPF2 ), Bitmap.Width - 1 );
   LY := Max( Floor( CenterY - RPF2 ), 0 );
   RY := Min(Ceil( CenterY + RPF2 ), Bitmap.Height - 1 );

   // Optimization run: find squares of X first
   SetLength( SqX, RX - LX + 1 );
   for x := LX to RX do
      SqX[x-LX] := Sqr( x - CenterX );

   // Loop through Y values
   for y := LY to RY do
   begin
      P := Bitmap.Scanline[y];
      SqY := Sqr( y - CenterY );
      // Loop through X values
      for x := LX to RX do
      begin
         // determine squared distance from center for this pixel
         SqDist := SqY + SqX[x - LX];

         // inside inner circle? Most often..
         if sqdist < RMF2 then
         begin
            // inside the inner circle.. just give the scanline the new color
            P[x] := 255
         end
         else
         begin
            // inside outer circle?
            if sqdist < RPF2 then
            begin
               // We are inbetween the inner and outer bound, now mix the color
               Fact := Round( ( ( Radius - Sqrt( SqDist ) ) * 2 / Feather ) * 127.5 + 127.5 );
               P[x] := Max( 0, Min( Fact, 255 ) ); // just in case limit to [0, 255]
            end
            else
            begin
               P[x] := 0;
            end;
         end;
      end;
   end;
end;

procedure DrawCircle( Bitmap: TBitmap; CenterX, CenterY, Radius, LineWidth, Feather: Single );
// Draw a circle on Bitmap. Bitmap must be a 256 color (pf8bit) palette bitmap,
// and parts outside the circle will get palette index 0, parts inside will get
// palette index 255, and in the antialiased area (feather), the pixels will
// get values inbetween.
// ***Parameters***
// Bitmap:
//   The bitmap to draw on
// CenterX, CenterY:
//   The center of the circle (float precision). Note that [0, 0] would be the
//   center of the first pixel. To draw in the exact middle of a 100x100 bitmap,
//   use CenterX = 49.5 and CenterY = 49.5
// Radius:
//   The radius of the drawn circle in pixels (float precision)
// LineWidth
//   The line width of the drawn circle in pixels (float precision)
// Feather:
//   The feather area. Use 1 pixel for a 1-pixel antialiased area. Pixel centers
//   outside 'Radius + Feather / 2' become 0, pixel centers inside 'Radius - Feather/2'
//   become 255. Using a value of 0 will yield a bilevel image. Note that Feather
//   must be equal or smaller than LineWidth (or it will be adjusted internally)
// Copyright (c) 2003 Nils Haeck M.Sc. www.simdesign.nl
var
  x, y: integer;
  LX, RX, LY, RY: integer;
  Fact: integer;
  ROPF2, ROMF2, RIPF2, RIMF2: single;
  OutRad, InRad: single;
  P: PByteArray;
  SqY, SqDist: single;
  sqX: array of single;
begin
   // Determine some helpful values (singles)
   OutRad := Radius + LineWidth/2;
   InRad  := Radius - LineWidth/2;
   ROPF2 := Sqr( OutRad + Feather/2 );
   ROMF2 := Sqr( OutRad - Feather/2 );
   RIPF2 := Sqr( InRad  + Feather/2 );
   RIMF2 := Sqr( InRad  - Feather/2 );

   // Determine bounds:
   LX := Max( Floor( CenterX - ROPF2 ), 0 );
   RX := Min( Ceil ( CenterX + ROPF2 ), Bitmap.Width - 1 );
   LY := Max( Floor( CenterY - ROPF2 ), 0 );
   RY := Min( Ceil ( CenterY + ROPF2 ), Bitmap.Height - 1 );

   // Checks
   if Feather > LineWidth then
      Feather := LineWidth;

   // Optimization run: find squares of X first
   SetLength( SqX, RX - LX + 1 );
   for x := LX to RX do
      SqX[x - LX] := Sqr( x - CenterX );

   // Loop through Y values
   for y := LY to RY do
   begin
      P := Bitmap.Scanline[y];
      SqY := Sqr( y - CenterY );
      // Loop through X values
      for x := LX to RX do
      begin
         // determine squared distance from center for this pixel
         SqDist := SqY + SqX[x - LX];

         // now first check if we're completely inside (most often)
         if SqDist < RIMF2 then
         begin
            // We're on the disk inside everything
            P[x] := 0;
         end
         else
         begin
            // completely outside?
            if SqDist < ROPF2 then
            begin
               // inside outer line - feather?
               if SqDist < ROMF2 then
               begin
                  // check if we're in inside feather area
                  if SqDist < RIPF2 then
                  begin
                     // We are in the feather area of inner line, now mix the color
                     Fact := Round( ( ( Sqrt( SqDist ) - InRad ) * 2 / Feather ) * 127.5 + 127.5 );
                     P[x] := Max( 0, Min( Fact, 255 ) ); // just in case limit to [0, 255]
                  end
                  else
                  begin
                     // on the line
                     P[x] := 255;
                  end;
               end
               else
               begin
                  // We are in the feather area of outer line, now mix the color
                  Fact := Round( ( ( OutRad - Sqrt( SqDist ) ) * 2 / Feather ) * 127.5 + 127.5 );
                  P[x] := Max( 0, Min( Fact, 255 ) ); // just in case limit to [0, 255]
               end;
            end
            else
            begin
               // outside everything
               P[x] := 0;
            end;
         end;
      end;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
// Create a 256-color bitmap and call the DrawCircle procedure
var
  i, y: integer;
  ABitmap: TBitmap;
  pal: PLogPalette;
  hpal: HPALETTE;
  ColRGB, BgrRGB: integer;
  ACenterX, ACenterY,
  ARadius, AFeather,
  ALineWidth: single;
begin
   ABitmap := TBitmap.Create;
   try
      // 8 bits per pixel
      ABitmap.PixelFormat := pf8bit;

      // Set width and height
      ABitmap.Width := 300;
      ABitmap.Height := 300;

      // Create a gradient palette between foreground and background color
      GetMem( pal, SizeOf( TLogPalette ) + SizeOf( TPaletteEntry ) * 255 );
      try
         pal.palVersion := $300;
         pal.palNumEntries := 256;
         ColRGB := ColorToRGB( clWhite );
         BgrRGB := ColorToRGB( clBlack );
         for i := 0 to 255 do
         begin
            pal.palPalEntry[i].peRed   := Round( i / 255 * ( ColRGB        and $FF ) + ( 255 - i ) / 255 * ( BgrRGB        and $FF ) );
            pal.palPalEntry[i].peGreen := Round( i / 255 * ( ColRGB shr 8  and $FF ) + ( 255 - i ) / 255 * ( BgrRGB shr 8  and $FF ) );
            pal.palPalEntry[i].peBlue  := Round( i / 255 * ( ColRGB shr 16 and $FF ) + ( 255 - i ) / 255 * ( BgrRGB shr 16 and $FF ) );
         end;
         hpal := CreatePalette( pal^ );
         if hpal <> 0 then
            ABitmap.Palette := hpal;
      finally
         FreeMem( pal );
      end;

      // Fill bitmap with background color
      for y := 0 to ABitmap.Height-1 do
         FillChar( ABitmap.Scanline[y]^, ABitmap.Width, 0 );

      // Get data from form
      ACenterX := 150;
      ACenterY := 150;
      ARadius := 135.5;
      ALineWidth := 10;
      AFeather := 5;

      // Рисуем диск
      DrawDisk( ABitmap, ACenterX, ACenterY, ARadius, AFeather );
      // Рисуем окружность
      // DrawCircle( ABitmap, ACenterX, ACenterY, ARadius, ALineWidth, AFeather );

      // Assign to image
      imMain.Picture.Bitmap.Assign( ABitmap );
   finally
      ABitmap.Free;
   end;
end;


Как вытащить маску из TIcon?

type
  TForm1 = class(TForm)
    procedure FormPaint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    Mask: TBitmap;
  public
  end;


implementation

procedure TForm1.FormCreate(Sender: TObject);
var
  IconInfo: TIconInfo;
begin
   Mask := TBitmap.Create;
   GetIconInfo( Application.Icon.Handle, IconInfo );
   Mask.Handle := IconInfo.hbmMask;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
   Mask.Free;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
   BitBlt( Canvas.Handle, 0, 0, Mask.Width, Mask.Height,
           Mask.Canvas.Handle, 0, 0, SRCCOPY );
end;


Как начертить hexagon?

uses
  {...,} Math;

procedure PlotPolygon( const Canvas: TCanvas; const N: Integer; const R: Single;
 const XC: Integer; const YC: Integer );
type
  TPolygon = array of TPoint;
var
  Polygon: TPolygon;
  I: Integer;
  C: Extended;
  S: Extended;
  A: Single;
begin
   SetLength( Polygon, N );
   A := 2 * Pi / N;
   for I := 0 to ( N - 1 ) do
   begin
      SinCos( I * A, S, C );
      Polygon[I].X := XC + Round( R * C );
      Polygon[I].Y := YC + Round( R * S );
   end;
   Canvas.Polygon( Polygon );
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  W: Single;
  H: Single;
  X: Integer;
  Y: Integer;
const
  N = 6;
  R = 10;
begin
   W := 1.5 * R;
   H := R * Sqrt( 3 );
   for X := 0 to Round( ClientWidth / W ) do
      for Y := 0 to Round( ClientHeight / H ) do
         if Odd( X ) then
            PlotPolygon( Canvas, N, R, Round( X * W ), Round( ( Y + 0.5 ) * H ) )
         else
            PlotPolygon( Canvas, N, R, Round( X * W ), Round( Y * H ) );
end;


Как вывести надпись на Canvas с эффектом 3D?

procedure ExtFont( Canvas: TCanvas );
var
  Font: HFONT;
  FontName, Txt: PChar;
  sSize: Size;
  i: integer;
  Obj: LongWord;
begin
   FontName := 'Tahoma';
   Txt := 'www.decoding.dax.ru';
   Font := CreateFont( 60, 30, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET,
                       OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
                       PROOF_QUALITY, DEFAULT_PITCH + FF_DONTCARE, FontName );
   Obj := SelectObject( Canvas.Handle, Font );
   SetBkMode( Canvas.Handle, TRANSPARENT );
   GetTextExtentPoint32( Canvas.Handle, Txt, Length( Txt ), sSize );
   BeginPath( Canvas.Handle );
   Canvas.Pen.Color:= clGreen; // Цвет текста
   i := 1;
   for i := 0 to 2 do  // Глубина эффекта
      // Позиция текста на форме
      TextOut( Canvas.Handle, 5 + i, 10 + i, Txt, Length( Txt ) );
   EndPath( Canvas.Handle );
   // Canvas.Pen.Style := psDot;  { Стиль }
   StrokePath( Canvas.Handle );
   SetBkMode( Canvas.Handle, OPAQUE );
   DeleteObject( Obj );
   DeleteObject( Font );
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
   ExtFont( Canvas );
end;


Как перевести пиксели в миллиметры?

// Способ первый
// Имеет меньшую точность и не реагирует на изменение разрешения экрана
function PixelsToMM( WidthInPixels: Cardinal ): Extended;
begin
   Result := WidthInPixels / Screen.PixelsPerInch * 25.4;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage( FloatToStr( PixelsToMM( 10 ) ) );
end;

// Способ второй
// Имеет меньшую точность и не реагирует на изменение разрешения экрана
procedure PixelsToMM( DC: HDC; WidthInPixels: Cardinal;
  var WidthInMM, HeightInMM: Extended );
begin
   WidthInMM := WidthInPixels * 25.4 / GetDeviceCaps( DC, LOGPIXELSX );
   HeightInMM := WidthInPixels * 25.4 / GetDeviceCaps( DC, LOGPIXELSY );
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  WidthInMM, HeightInMM: Extended;
begin
   PixelsToMM( GetDC( HWND( nil ) {0} ), 10, WidthInMM, HeightInMM );
   ShowMessage( 'W: ' + FloatToStr( WidthInMM ) + '   H: ' + FloatToStr( HeightInMM ) );
end;

// Способ третий
// Имеет бОльшую точность
procedure PixelsToMM( DC: HDC; WidthInPixels, HeightInPixels: Cardinal;
  var WidthInMM, HeightInMM: Extended );
var
  HRes, VRes, HSiz, VSiz: Integer;
begin
   HRes := GetDeviceCaps( DC, HORZRES );
   VRes := GetDeviceCaps( DC, VERTRES );
   HSiz := GetDeviceCaps( DC, HORZSIZE );
   VSiz := GetDeviceCaps( DC, VERTSIZE );
   WidthInMM := WidthInPixels / ( HRes / HSiz );
   HeightInMM := HeightInPixels / ( VRes / VSiz );
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  WidthInMM, HeightInMM: Extended;
begin
   PixelsToMM( GetDC( HWND( nil ) {0} ), 10, 10, WidthInMM, HeightInMM );
   ShowMessage( 'W: ' + FloatToStr( WidthInMM ) + '   H: ' + FloatToStr( HeightInMM ) );
end;


Как перевести миллиметры в пиксели?

// Способ первый
// Имеет меньшую точность и не реагирует на изменение разрешения экрана
function MMToPixels( WidthInMM: Extended ): Cardinal;
begin
   Result := Round( Screen.PixelsPerInch / 25.4 * WidthInMM );
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
   ShowMessage( IntToStr( MMToPixels( 2.64583333333333 ) ) );
end;

// Способ второй
// Имеет меньшую точность и не реагирует на изменение разрешения экрана
procedure MMToPixels( DC: HDC; WidthInMM: Extended;
  var WidthInPixels, HeightInPixels: Cardinal );
begin
   WidthInPixels := Round( GetDeviceCaps( DC, LOGPIXELSX ) / 25.4 * WidthInMM );
   HeightInPixels := Round( GetDeviceCaps( DC, LOGPIXELSY ) / 25.4 * WidthInMM );
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  WidthInPixels, HeightInPixels: Cardinal;
begin
   MMToPixels( GetDC( HWND( nil ) {0} ), 2.64583333333333, WidthInPixels, HeightInPixels );
   ShowMessage( 'W: ' + IntToStr( WidthInPixels ) + '   H: ' + IntToStr( HeightInPixels ) );
end;

// Способ третий
// Имеет бОльшую точность
procedure MMToPixels( DC: HDC; WidthInMM, HeightInMM: Extended;
  var WidthInPixels, HeightInPixels: Cardinal );
var
  HRes, VRes, HSiz, VSiz: Integer;
begin
   HRes := GetDeviceCaps( DC, HORZRES );
   VRes := GetDeviceCaps( DC, VERTRES );
   HSiz := GetDeviceCaps( DC, HORZSIZE );
   VSiz := GetDeviceCaps( DC, VERTSIZE );
   WidthInPixels := Round( WidthInMM * ( HRes / HSiz ) );
   HeightInPixels := Round( HeightInMM * ( VRes / VSiz ) );
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  WidthInPixels, HeightInPixels: Cardinal;
begin
   MMToPixels( GetDC( HWND( nil ) {0} ), 3.52604166666667, 3.52777777777778, WidthInPixels, HeightInPixels );
   ShowMessage( 'W: ' + IntToStr( WidthInPixels ) + '   H: ' + IntToStr( HeightInPixels ) );
end;


Как рассчитать переходный цвет между двумя исходными?

uses
  Math;

const
  C1: TColor = clRed;
  C2: TColor = clLime;

function getNearestColor( const aColor1, aColor2: TColor; const aRate: Single ): TColor;
var
  r, r1,
  g, g1,
  b, b1: Byte;
begin
   Assert( ( aRate >= 0 ) and ( aRate <= 100 ), 'Изменение цвета должно быть меньше 100% разницы цветов' );
   // Раскладываем цвета на компоненты
   r := GetRValue( aColor2 );
   g := GetGValue( aColor2 );
   b := GetBValue( aColor2 );
   r1 := GetRValue( aColor1 );
   g1 := GetGValue( aColor1 );
   b1 := GetBValue( aColor1 );
   Result:= RGB( r1 - Floor( ( r1 - r ) * ( aRate / 100 ) ),
                 g1 - Floor( ( g1 - g ) * ( aRate / 100 ) ),
                 b1 - Floor( ( b1 - b ) * ( aRate / 100 ) ) );
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   Canvas.Brush.Color := getNearestColor( C1, C2, 50 );
   Canvas.FillRect( ClientRect );
end;


Как рассчитать последовательность переходных цветов между двумя исходными?

type
  TForm1 = class(TForm)
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Image5: TImage;
    Image6: TImage;
    Image7: TImage;
    Image8: TImage;
    Image9: TImage;
    Image10: TImage;
    procedure FormCreate(Sender: TObject);
  private
    GradArr: array[1..10] of TColor;
  public
  end;

implementation

uses
  Math;

function GetColorInterval( Color1, Color2: TColor; IntervalCount, IntervalIndex: Byte ): TColor;
const
  STEP = 256;
var
  // Компоненты цвета
  r1, r2,
  g1, g2,
  b1, b2: Byte;
begin
   r1 := GetRValue( Color1 );
   g1 := GetGValue( Color1 );
   b1 := GetBValue( Color1 );

   r2 := GetRValue( Color2 );
   g2 := GetGValue( Color2 );
   b2 := GetBValue( Color2 );

   Result := RGB( Byte( Floor( r1 + ( r2 - r1 ) * Trunc( STEP / ( IntervalCount + 1 ) * IntervalIndex ) / STEP ) ),
                  Byte( Floor( g1 + ( g2 - g1 ) * Trunc( STEP / ( IntervalCount + 1 ) * IntervalIndex ) / STEP ) ),
                  Byte( Floor( b1 + ( b2 - b1 ) * Trunc( STEP / ( IntervalCount + 1 ) * IntervalIndex ) / STEP ) ) );
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  Img: TImage;
begin
   GradArr[1] := clYellow; // Начальный цвет
   GradArr[10] := clRed;   // Конечный цвет

   for i := 1 to 8 do // Нам нужно 8 градаций
      GradArr[i+1] := GetColorInterval( GradArr[1], GradArr[10], 8, i );

   for i := 1 to 10 do
   begin
      Img := TImage( FindComponent( 'Image' + IntToStr( i ) ) );
      if Assigned( Img ) then
      begin
         Img.Canvas.Brush.Color := GradArr[i];
         Img.Canvas.FillRect( Rect( 0, 0, Img.Width, Img.Height ) );
      end;
   end;
end;

При использовании материала - ссылка на сайт обязательна