Skip to content

TSVGIconMultiResBitmap (FMX)

Unit: FMX.SVGIconImageList

Inherits from: TMultiResBitmap

Description

TSVGIconMultiResBitmap manages a collection of bitmaps at different scale factors (1x, 1.5x, 2x, 3x) for a single SVG icon. This class is used internally by TSVGIconSourceItem to provide automatic multi-resolution bitmap generation, ensuring sharp icon rendering on all devices from standard displays to Retina screens and mobile devices.

The component automatically generates appropriate bitmaps based on the device's scale factor, eliminating the need for manual bitmap management.

Purpose

TSVGIconMultiResBitmap solves the cross-platform multi-DPI challenge:

  • Standard displays (96 DPI) → 1x bitmaps
  • Medium DPI (144 DPI) → 1.5x bitmaps
  • Retina/High-DPI (192 DPI) → 2x bitmaps
  • Ultra-high DPI (288+ DPI) → 3x bitmaps

Properties

Collection Items

The bitmap collection contains TSVGIconBitmapItem objects, each representing one scale factor.

Inherited from TMultiResBitmap

pascal
property Items[Index: Integer]: TSVGIconBitmapItem;
property Count: Integer;

Access bitmap items by index or scale factor.

Example:

pascal
var
  MultiResBitmap: TSVGIconMultiResBitmap;
  BitmapItem: TSVGIconBitmapItem;
begin
  MultiResBitmap := Icon.MultiResBitmap as TSVGIconMultiResBitmap;

  // Access by index
  BitmapItem := MultiResBitmap.Items[0] as TSVGIconBitmapItem;

  // Access by scale
  BitmapItem := MultiResBitmap.ItemByScale(2.0, False) as TSVGIconBitmapItem;
end;

Methods

ItemByScale

pascal
function ItemByScale(const AScale: Single; const ExactMatch: Boolean): TSVGIconBitmapItem;

Retrieves bitmap item for specified scale factor.

Parameters:

  • AScale: Scale factor (e.g., 1.0, 1.5, 2.0, 3.0)
  • ExactMatch: When True, returns only exact matches; when False, returns closest match

Returns: TSVGIconBitmapItem or nil

Example:

pascal
var
  BitmapItem: TSVGIconBitmapItem;
begin
  // Get exact 2x bitmap
  BitmapItem := MultiResBitmap.ItemByScale(2.0, True) as TSVGIconBitmapItem;

  // Get closest to 2.5x (might return 2x or 3x)
  BitmapItem := MultiResBitmap.ItemByScale(2.5, False) as TSVGIconBitmapItem;
end;

TSVGIconBitmapItem

Each bitmap item in the collection is a TSVGIconBitmapItem with these properties:

Properties

Scale: Single

pascal
property Scale: Single;

The scale factor for this bitmap (1.0, 1.5, 2.0, 3.0).

Size: Integer

pascal
property Size: Integer;

Uniform size for square bitmaps.

Width: Integer

pascal
property Width: Integer;

Bitmap width in pixels.

Height: Integer

pascal
property Height: Integer;

Bitmap height in pixels.

Zoom: Integer

pascal
property Zoom: Integer default 100;

Zoom percentage (10-100).

Bitmap: TBitmap

pascal
property Bitmap: TBitmapOfItem;

The rendered bitmap (auto-generated, not stored).

Read-Only Rendering Properties

These properties are inherited from the parent TSVGIconSourceItem:

pascal
property FixedColor: TAlphaColor; // Read-only
property ApplyFixedColorToRootOnly: Boolean; // Read-only
property GrayScale: Boolean; // Read-only
property Opacity: Single; // Read-only

Usage Examples

Access Specific Scale Bitmap

pascal
procedure TForm1.GetRetinaBitmap;
var
  Icon: TSVGIconSourceItem;
  MultiResBitmap: TSVGIconMultiResBitmap;
  BitmapItem: TSVGIconBitmapItem;
  Bitmap: TBitmap;
begin
  Icon := SVGIconImageList1.GetIconByName('home');
  MultiResBitmap := Icon.MultiResBitmap as TSVGIconMultiResBitmap;

  // Get 2x (Retina) bitmap
  BitmapItem := MultiResBitmap.ItemByScale(2.0, False) as TSVGIconBitmapItem;

  if Assigned(BitmapItem) then
  begin
    Bitmap := BitmapItem.Bitmap;
    // Use bitmap...
  end;
end;

Enumerate All Scale Factors

pascal
procedure TForm1.ListScaleFactors;
var
  Icon: TSVGIconSourceItem;
  MultiResBitmap: TSVGIconMultiResBitmap;
  I: Integer;
  BitmapItem: TSVGIconBitmapItem;
begin
  Icon := SVGIconImageList1.GetIcon(0);
  MultiResBitmap := Icon.MultiResBitmap as TSVGIconMultiResBitmap;

  Memo1.Lines.Clear;
  for I := 0 to MultiResBitmap.Count - 1 do
  begin
    BitmapItem := MultiResBitmap.Items[I] as TSVGIconBitmapItem;
    Memo1.Lines.Add(Format('Scale: %.1fx - Size: %dx%d',
      [BitmapItem.Scale, BitmapItem.Width, BitmapItem.Height]));
  end;
end;

Check Available Scales

pascal
procedure TForm1.CheckScales;
var
  Icon: TSVGIconSourceItem;
  MultiResBitmap: TSVGIconMultiResBitmap;
  Scales: array of Single;
  I: Integer;
begin
  Icon := SVGIconImageList1.GetIconByName('settings');
  MultiResBitmap := Icon.MultiResBitmap as TSVGIconMultiResBitmap;

  SetLength(Scales, 4);
  Scales[0] := 1.0;
  Scales[1] := 1.5;
  Scales[2] := 2.0;
  Scales[3] := 3.0;

  for I := 0 to High(Scales) do
  begin
    if Assigned(MultiResBitmap.ItemByScale(Scales[I], True)) then
      ShowMessage(Format('%.1fx bitmap available', [Scales[I]]))
    else
      ShowMessage(Format('%.1fx bitmap NOT available', [Scales[I]]));
  end;
end;

Get Bitmap for Current Screen

pascal
procedure TForm1.GetCurrentScaleBitmap;
var
  Icon: TSVGIconSourceItem;
  MultiResBitmap: TSVGIconMultiResBitmap;
  BitmapItem: TSVGIconBitmapItem;
  CurrentScale: Single;
begin
  Icon := SVGIconImageList1.GetIcon(0);
  MultiResBitmap := Icon.MultiResBitmap as TSVGIconMultiResBitmap;

  // Get current screen scale
  CurrentScale := Form1.Handle.Scale;

  // Get best matching bitmap
  BitmapItem := MultiResBitmap.ItemByScale(CurrentScale, False) as TSVGIconBitmapItem;

  if Assigned(BitmapItem) then
    ShowMessage(Format('Using %.1fx bitmap for %.1fx screen',
      [BitmapItem.Scale, CurrentScale]));
end;

Export Bitmap at Specific Scale

pascal
procedure TForm1.ExportBitmapAtScale(const AScale: Single; const AFileName: string);
var
  Icon: TSVGIconSourceItem;
  MultiResBitmap: TSVGIconMultiResBitmap;
  BitmapItem: TSVGIconBitmapItem;
begin
  Icon := SVGIconImageList1.GetIconByName('logo');
  MultiResBitmap := Icon.MultiResBitmap as TSVGIconMultiResBitmap;

  BitmapItem := MultiResBitmap.ItemByScale(AScale, False) as TSVGIconBitmapItem;

  if Assigned(BitmapItem) then
    BitmapItem.Bitmap.SaveToFile(AFileName)
  else
    ShowMessage(Format('No bitmap available for scale %.1fx', [AScale]));
end;

Compare Bitmap Sizes

pascal
procedure TForm1.CompareBitmapSizes;
var
  Icon: TSVGIconSourceItem;
  MultiResBitmap: TSVGIconMultiResBitmap;
  Item1x, Item2x, Item3x: TSVGIconBitmapItem;
begin
  Icon := SVGIconImageList1.GetIcon(0);
  MultiResBitmap := Icon.MultiResBitmap as TSVGIconMultiResBitmap;

  Item1x := MultiResBitmap.ItemByScale(1.0, True) as TSVGIconBitmapItem;
  Item2x := MultiResBitmap.ItemByScale(2.0, True) as TSVGIconBitmapItem;
  Item3x := MultiResBitmap.ItemByScale(3.0, True) as TSVGIconBitmapItem;

  Memo1.Lines.Clear;
  if Assigned(Item1x) then
    Memo1.Lines.Add(Format('1x: %dx%d pixels', [Item1x.Width, Item1x.Height]));
  if Assigned(Item2x) then
    Memo1.Lines.Add(Format('2x: %dx%d pixels', [Item2x.Width, Item2x.Height]));
  if Assigned(Item3x) then
    Memo1.Lines.Add(Format('3x: %dx%d pixels', [Item3x.Width, Item3x.Height]));
end;

Automatic Bitmap Generation

When TSVGIconImageList.AutoSizeBitmaps = True (default), bitmaps are generated automatically:

pascal
// With AutoSizeBitmaps = True
SVGIconImageList1.Size := 32;

// Automatically generates:
// - 32x32 @ 1x scale
// - 48x48 @ 1.5x scale
// - 64x64 @ 2x scale
// - 96x96 @ 3x scale

Scale Factor Selection Algorithm

FMX automatically selects the best bitmap based on:

  1. Current screen scale factor
  2. Exact match first - If available, uses bitmap at exact scale
  3. Closest match - If no exact match, uses nearest scale
  4. Scale up/down - Scales bitmap if necessary

Example:

Screen Scale: 2.5x
Available: 1x, 2x, 3x
Selected: 3x (closest match)
Result: 3x bitmap scaled down slightly

Memory Considerations

Each TSVGIconMultiResBitmap typically contains 4 bitmaps (1x, 1.5x, 2x, 3x).

Memory usage example for 32x32 base size:

1.0x: 32x32 = 1,024 pixels
1.5x: 48x48 = 2,304 pixels
2.0x: 64x64 = 4,096 pixels
3.0x: 96x96 = 9,216 pixels
Total: ~16,640 pixels per icon

For 100 icons:

  • ~1.6 million pixels
  • ~6.4 MB (at 32-bit color)

Platform-Specific Behavior

Windows

  • Standard displays: 1x (96 DPI)
  • High-DPI displays: 1.5x, 2x, or higher based on scaling

macOS

  • Standard displays: 1x
  • Retina displays: 2x automatically

iOS

  • Non-Retina (older): 1x
  • Retina: 2x (iPhone 4-8)
  • Retina HD: 3x (iPhone 6+ and newer)

Android

  • MDPI (~160 DPI): 1x
  • HDPI (~240 DPI): 1.5x
  • XHDPI (~320 DPI): 2x
  • XXHDPI (~480 DPI): 3x

See Also

Released under Apache License, Version 2.0.