Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2022年11月18日] [更新 2022年11月19日] Delphi サンプルプログラム集
   
093_実行時に TImageList に画像を格納
動作確認等 Windows 10 ビルド 19043 Pro 64 bit + Delphi XE5(UP2) Pro VCL-32
093_TImageList_SetImage.zip [6.5 MB] 2022年11月19日版 (EXE 同梱)







実行時に TImageList に画像を格納


実行時に,TImageList に画像を格納するサンプルです.
TImageList に格納される画像は,TImageList の ColorDepth プロパティに応じたビット深さのビットマップとなります.



TImageList の ColorDepth プロパティの値は,デフォルトでは cdDeviceDependent です.これはデバイス依存の処理です.本ページのサンプルでは.cd32bit にしてテストしています.cd32bit は,32 ビット画像のアルファ値も処理する方式です.
TImageList には,Width, Height プロパティで指定したサイズの画像だけが格納できます.それよりも大きいサイズの画像格納すると,Width, Height プロパティのサイズに分割して格納されます.

TImageList に格納したビットマップ画像を確認するために,本ページのサンプルでは,TListView コントロールに vsIcon として描画するようにしています.




図1
TImagelIst のオブジェクト・インスペクタ
  • ColorDepth の値を cd32bit に変更
    デフォルトは cdDeviceDependent
  • 格納する画像サイズは 128 x 128

本ページのサンプルをコンパイルすると,次のようなメッセージが表示されることがあります.この .vrc ファイルは,TImagelist に画像を格納する処理の際に生成される一時ファイルです.


ファイル "Project1.vrc" を削除しています。





01_TImageList に 32 ビットのビットマップ画像を格納


32 ビットのビットマップ画像を TImageList に格納して,TListView へ描画した結果です.
左の元の画像は,32 ビットのアルファチャンネル付きのビットマップです.透明色が透過ピクセルになります.この場合,TImageList に格納する際に,マスク画像は必要ありません.マスク画像を作成して Add メソッドの引数に渡しても結果は同じです.
右の元の画像は,32 ビットのビットマップですが,アルファ値は使用していません.しがって,事実上 24 ビット色のビットマップ画像と同じです.下図では,マスク画像を使用していないので透過ピクセルはありません.




図2
TListView への描画結果
  • 左の元画像は,
    32 ビットのアルファチャンネル付きのビットマップ
  • 右の元画像は,
    32 ビットのアルファ値を使用しないビットマップ

[Button2] をクリックして,マスク画像を使用した結果が下図です.TBitmap の画像は,特に指定しない場合,左下のピクセルの色が透過色になります.




図3
TListView への描画結果
  • 左の元画像は,
    32 ビットのアルファチャンネル付きのビットマップ
  • 右の元画像は,
    32 ビットのアルファ値を使用しないビットマップ

リスト1
TImageList に 32 ビットのビットマップ画像を格納
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ImgList, Vcl.ComCtrls,
  Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ImageList1: TImageList;
    ListView1: TListView;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//  透過状態の確認用に TListView の背景色を設定
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ImageList1.SetSize(128, 128);
  // Delphi 2009 以降では cd32bit にする
  ImageList1.ColorDepth := cd32Bit;

  ListView1.Items.Clear;
  ListView1.Color := clSilver;
  ListView1.ViewStyle   := vsIcon;
  ListView1.LargeImages := ImageList1;
end;

//=============================================================================
//  32 ビット色のビットマップ画像を格納
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LBitmap     : TBitmap;
  LMaskBitmap : TBitmap;
  LIndex      : Integer;
begin
  ListView1.Items.Clear;
  ImageList1.Clear;

  LBitmap     := TBitmap.Create;
  LMaskBitmap := TBitmap.Create;
  try
    // 32 ビットのアルファチャンネル付きビットマップ
    LBitmap.LoadFromFile('..\Images\simple_32bit_AlphaZero.bmp');
    ImageList1.Add(LBitmap, nil);

    // 32 ビットのアルファチャンネルなしのビットマップ
    LBitmap.LoadFromFile('..\Images\simple_32bit.bmp');

    // Sender が nil の時はマスク画像を追加
    if Sender <> nil then begin
      ImageList1.Add(LBitmap, nil);
    end else begin
      LMaskBitmap.Assign(LBitmap);
      LMaskBitmap.Mask(LBitmap.TransparentColor);
      ImageList1.Add(LBitmap, LMaskBitmap);
    end;
  finally
    FreeAndNil(LBitmap);
    FreeAndNil(LMaskBitmap);
  end;


  // TListView に TImageList の画像を描画
  for LIndex := 0 to ImageList1.Count - 1 do begin
    ListView1.Items.Add.Caption := 'Image - ' + IntToStr(LIndex);
    ListView1.Items[LIndex].ImageIndex := LIndex;
  end;
end;

//=============================================================================
//  32 ビット色のビットマップ画像を格納
//  マスク画像を使用する処理
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  Button1Click(nil);
end;

end.


マスク画像は下図のようになります.黒以外の部分が透過ピクセルとなります.

32 ビットのアルファチャンネル付きのビットマップでは,マスク画像を使用する必要はありませんが,マスク画像を使用しても結果は同じです.
したがって,32 ビットのビットマップの場合,アルファチャンネルを使用していても,使用していなくとも同じ処理で TImageList に格納できます.




図4
マスク画像
  • 黒以外の部分が透過ピクセル

//=============================================================================
//  マスク画像を作成して TImage に描画
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LBitmap : TBitmap;
begin
  Image1.Picture.Assign(nil);

  LBitmap     := TBitmap.Create;
  try
    // 32 ビットのアルファチャンネルなしのビットマップ
    LBitmap.LoadFromFile('..\Images\simple_32bit.bmp');

    LBitmap.Mask(LBitmap.TransparentColor);
    Image1.Canvas.Draw(0, 0, LBitmap);
  finally
    FreeAndNil(LBitmap);
  end;
end;




02_TImageList に 32 ビット以外のビットマップ画像を格納


32 ビット以外のピッマップ画像の場合も同じです.
以下のサンプルは,8 ビットのビットマップ画像を,TImageList に格納する例です.




図5
マスク画像を使用しない場合
  • 左の元画像は比較用で,
    32 ビットのアルファチャンネル付きのビットマップ
  • 右の元画像は,
    8 ビットのビットマップ画像

図6
マスク画像を使用した場合
  • 左の元画像は比較用で,
    32 ビットのアルファチャンネル付きのビットマップ
  • 右の元画像は,
    8 ビットのビットマップ画像

リスト2
TImageList に 32 ビット以外のビットマップ画像を格納
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ImgList, Vcl.ComCtrls,
  Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ImageList1: TImageList;
    ListView1: TListView;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//  透過状態の確認用に TListView の背景色を設定
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ImageList1.SetSize(128, 128);
  // cd32bit にする
  ImageList1.ColorDepth := cd32Bit;

  ListView1.Items.Clear;
  ListView1.Color := clSilver;
  ListView1.ViewStyle   := vsIcon;
  ListView1.LargeImages := ImageList1;
end;

//=============================================================================
//  24 ビット色以下ののビットマップ画像を格納
//  マスク画像を使用しない場合
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LBitmap : TBitmap;
  LIndex  : Integer;
begin
  ListView1.Items.Clear;
  ImageList1.Clear;

  LBitmap := TBitmap.Create;
  try
    // 32 ビットのアルファチャンネル付きビットマップ ( 比較用 )
    LBitmap.LoadFromFile('..\Images\simple_32bit_AlphaZero.bmp');
    ImageList1.Add(LBitmap, nil);

    // 8 ビット色 (256 色) のビットマップ画像
    LBitmap.LoadFromFile('..\Images\simple_8bit.bmp');
    ImageList1.Add(LBitmap, nil);
  finally
    FreeAndNil(LBitmap);
  end;


  // TListView に TImageList の画像を描画
  for LIndex := 0 to ImageList1.Count - 1 do begin
    ListView1.Items.Add.Caption := 'Image - ' + IntToStr(LIndex);
    ListView1.Items[LIndex].ImageIndex := LIndex;
  end;
end;

//=============================================================================
//  24 ビット色以下ののビットマップ画像を格納
//  マスク画像を使用する場合
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LBitmap     : TBitmap;
  LMaskBitmap : TBitmap;
  LTransColor : TColor;
  LIndex      : Integer;
begin
  ListView1.Items.Clear;
  ImageList1.Clear;

  LBitmap     := TBitmap.Create;
  LMaskBitmap := TBitmap.Create;
  try
    // 32 ビットのアルファチャンネル付きビットマップ ( 比較用 )
    LBitmap.LoadFromFile('..\Images\simple_32bit_AlphaZero.bmp');
    ImageList1.Add(LBitmap, nil);

    // 8 ビット色 (256 色) のビットマップ画像
    // マスク画像を作成して Add メソッドの第 2 引数に渡す
    LBitmap.LoadFromFile('..\Images\simple_8bit.bmp');
    LMaskBitmap.Assign(LBitmap);
    LTransColor := LBitmap.Canvas.Pixels[0, LBitmap.Height - 1];
    LMaskBitmap.Mask(LTransColor);
    ImageList1.Add(LBitmap, LMaskBitmap);
  finally
    FreeAndNil(LBitmap);
    FreeAndNil(LMaskBitmap);
  end;


  // TListView に TImageList の画像を描画
  for LIndex := 0 to ImageList1.Count - 1 do begin
    ListView1.Items.Add.Caption := 'Image - ' + IntToStr(LIndex);
    ListView1.Items[LIndex].ImageIndex := LIndex;
  end;
end;

end.




03_TImageList に PNG 形式の画像を格納


TPngImage の画像を TImageList に格納する例です.
TPngImage の画像を TBitmap の画像に変換して,それを TImageList に追加します.マスク画像は必要ありません.




図7
PNG 画像を TImageList に格納
  • 左の元画像は比較用で,
    32 ビットのアルファチャンネル付きのビットマップ
  • 右の元画像は,
    32 ビットの PNG 画像

リスト3
TImageList に PNG 形式の画像を格納
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ImgList, Vcl.ComCtrls,
  Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ImageList1: TImageList;
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  Vcl.Imaging.pngimage;

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//  透過状態の確認用に TListView の背景色を設定
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ImageList1.SetSize(128, 128);
  // cd32bit にする
  ImageList1.ColorDepth := cd32Bit;

  ListView1.Items.Clear;
  ListView1.Color := clSilver;
  ListView1.ViewStyle   := vsIcon;
  ListView1.LargeImages := ImageList1;
end;

//=============================================================================
//  PNG 形式の画像を格納
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LBitmap   : TBitmap;
  LPngImage : TPngImage;
  LIndex    : Integer;
begin
  ListView1.Items.Clear;
  ImageList1.Clear;

  LBitmap    := TBitmap.Create;
  LPngImage := TPngImage.Create;
  try
    // 32 ビットのアルファチャンネル付きビットマップ ( 比較用 )
    LBitmap.LoadFromFile('..\Images\simple_32bit_AlphaZero.bmp');
    ImageList1.Add(LBitmap, nil);

    // PNG 画像を読み込んで TBitmap の画像に変換
    // それを TImageList に追加
    LPngImage.LoadFromFile('..\Images\simple_32bit.png');
    LBitmap.Assign(LPngImage);
    ImageList1.Add(LBitmap, nil);
  finally
    FreeAndNil(LBitmap);
    FreeAndNil(LPngImage);
  end;


  // TListView に TImageList の画像を描画
  for LIndex := 0 to ImageList1.Count - 1 do begin
    ListView1.Items.Add.Caption := 'Image - ' + IntToStr(LIndex);
    ListView1.Items[LIndex].ImageIndex := LIndex;
  end;
end;

end.




04_TImageList に GIF 形式の画像を格納


TGifImage の画像を TImageList に格納する例です.
TGIfImage の画像を TBitmap の画像に変換して,それを TImageList に追加します.マスク画像を作成して,Add メソッドの第 2 引数に渡します.




図8
GIF 画像を TImageList に格納
  • 左の元画像は比較用で,
    32 ビットのアルファチャンネル付きのビットマップ
  • 右の元画像は GIF 形式の画像

リスト4
TImageList に GIF 形式の画像を格納
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ImgList, Vcl.ComCtrls,
  Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ImageList1: TImageList;
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  Vcl.Imaging.GIFImg;

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//  透過状態の確認用に TListView の背景色を設定
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ImageList1.SetSize(128, 128);
  // cd32bit にする
  ImageList1.ColorDepth := cd32Bit;

  ListView1.Items.Clear;
  ListView1.Color := clSilver;
  ListView1.ViewStyle   := vsIcon;
  ListView1.LargeImages := ImageList1;
end;

//=============================================================================
//  GIF 形式の画像を格納
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LBitmap     : TBitmap;
  LMaskBitmap : TBitmap;
  LGifImage   : TGifImage;
  LIndex      : Integer;
begin
  ListView1.Items.Clear;
  ImageList1.Clear;

  LBitmap     := TBitmap.Create;
  LMaskBitmap := TBitmap.Create;
  LGifImage   := TGifImage.Create;
  try
    // 32 ビットのアルファチャンネル付きビットマップ ( 比較用 )
    LBitmap.LoadFromFile('..\Images\simple_32bit_AlphaZero.bmp');
    ImageList1.Add(LBitmap, nil);


    // GIF 画像を読み込んで TBitmap の画像に変換
    LGifImage.LoadFromFile('..\Images\Simple_8BIT.gif');

    // TBitmap に元の色を反映するために透過状態を解除
    LGifImage.Transparent := False;
    LBitmap.Canvas.Draw(0, 0, LGifImage);
    // マスク画像を作成して Add メソッドの第 2 引数に渡す
    LMaskBitmap.Assign(LBitmap);
    LMaskBitmap.Mask(LGifImage.Bitmap.TransparentColor);
    ImageList1.Add(LBitmap, LMaskBitmap);
  finally
    FreeAndNil(LBitmap);
    FreeAndNil(LMaskBitmap);
    FreeAndNil(LGifImage);
  end;


  // TListView に TImageList の画像を描画
  for LIndex := 0 to ImageList1.Count - 1 do begin
    ListView1.Items.Add.Caption := 'Image - ' + IntToStr(LIndex);
    ListView1.Items[LIndex].ImageIndex := LIndex;
  end;
end;

end.




05_TImageList に ICO 形式の画像を格納


TIcon 画像を TImageList に格納する例です.
TIcon 画像は,AddIcon メソッドで TImageList に格納できます.マスク画像を作成する必要はありません.TIcon 画像には,マスク画像が格納されています. TIcon は,そのマスク画像を使用して透過処理を行います.




図9
ICO 画像を TImageList に格納
  • 左の元画像は比較用で,
    32 ビットのアルファチャンネル付きのビットマップ
  • 右上は 32 ビットのアルファチャンネル付きの TIcon 画像
  • 左下は,24 ビットの TIcon 画像
  • 右下は,8 ビットの TIcon 画像

リスト5
TImageList に ICO 形式の画像を格納
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ImgList, Vcl.ComCtrls,
  Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ImageList1: TImageList;
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//  透過状態の確認用に TListView の背景色を設定
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ImageList1.SetSize(128, 128);
  // cd32bit にする
  ImageList1.ColorDepth := cd32Bit;

  ListView1.Items.Clear;
  ListView1.Color := clSilver;
  ListView1.ViewStyle   := vsIcon;
  ListView1.LargeImages := ImageList1;
end;

//=============================================================================
//  ICO 形式の画像を格納
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LBitmap : TBitmap;
  LIcon   : TIcon;
  LIndex  : Integer;
begin
  ListView1.Items.Clear;
  ImageList1.Clear;

  LBitmap := TBitmap.Create;
  LIcon   := TIcon.Create;
  try
    // 32 ビットのアルファチャンネル付きビットマップ ( 比較用 )
    LBitmap.LoadFromFile('..\Images\simple_32bit_AlphaZero.bmp');
    ImageList1.Add(LBitmap, nil);

    // 32 ビット色のアイコン画像を読み込んで AddIcon メソッドで TImageList に追加
    // 32 ビット色のアイコンはアルファチャンネル付きの画僧
    LIcon.LoadFromFile('..\Images\Images_32bIT.ico');
    ImageList1.AddIcon(LIcon);

    // 24 ビット色のアイコン画像を読み込んで AddIcon メソッドで TImageList に追加
    LIcon.LoadFromFile('..\Images\Images_24bIT.ico');
    ImageList1.AddIcon(LIcon);

    // 8 ビット色のアイコン画像を読み込んで AddIcon メソッドで TImageList に追加
    LIcon.LoadFromFile('..\Images\Images_8bIT.ico');
    ImageList1.AddIcon(LIcon);
  finally
    FreeAndNil(LBitmap);
    FreeAndNil(LIcon);
  end;


  // TListView に TImageList の画像を描画
  for LIndex := 0 to ImageList1.Count - 1 do begin
    ListView1.Items.Add.Caption := 'Image - ' + IntToStr(LIndex);
    ListView1.Items[LIndex].ImageIndex := LIndex;
  end;
end;

end.




06_ColorDepth プロパティが cd32bit 以外の場合


TImageList.ColorDepth プロパティの値が cd8bit の場合です.
cd8bit の場合は,TImageList に格納した画像は 8 ビットの 256 色の画像になります.24 ビット以上の画像は減色されますが,適切な減色処理が行われるわけではありりません.あらかじめ,適切な減色処理をしておくが必要があります.



下図は,ColorDepth プロパティの値が cd8bit の時に,32 ビットのアルファチャンネル付きの画像を TImageList に格納した結果です.

ColorDepth プロパティの値がデフォルトの cdDeviceDependent の時も,cd24bit の時も結果は同じです.アルファ値の処理は行われません.その結果,ビットマップでは「黒」と「透明色」が区別されないため,実際の「黒」と「透明色」のピクセルがどちらも黒になっています.半透明のピクセルの色は,R, G, B の値によって決まる値になります.

PNG 画像の場合は,背景を白で塗り潰してから描画します.透明ピクセルは,その背景色の「白」ままとなり,半透明のピクセルは背景色との混合色になます.

TIcon の画像の場合は,透過ピクセルは,透過ピクセルという情報に基づいて描画します.その結果,透過ピクセルは透過します.半透明のピクセルは減色処理されて黒に近い色になっています.




図10
元が 32 ビットの画像の場合
  • 全てアルファチャンネル付きの 32 ビット画像
  • 左上はビットマップ画像
  • 右上は TPingImage の画像
  • 左下は TIcon の画像

以下は,ColorDepth が cd8bit の時に,24 ビット以下の画像を TImageList に格納した例です.
このサンプルの,画像を TImageList へ格納する処理は,cd32bit の場合でもそのまま使用できます.つまり,ColorDepth を cd32bit にしておけば,アルファチャンネル付きの画像も,そうでない画像も,画像の質を損なうことなく TImageList に格納できます.




図11
元が 24 ビット以下の画像の場合
  • 左上は 24 ビットのビットマップ画像
  • 右上は TGifImage 画像
  • 左下は 24 ビットの TIcon 画像
  • 右下は 8 ビットの TIcon 画像

リスト6
ColorDepth プロパティが cd8bit の時に,画像を TImageList に格納
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ImgList, Vcl.ComCtrls,
  Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ImageList1: TImageList;
    ListView1: TListView;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  Vcl.Imaging.pngimage,
  Vcl.Imaging.GIFImg;

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//  ColorDepth の値を cd8bit にした場合のテスト
//  この場合,TImageList に格納されるのは 8 ビット色 ( 356 色 ) のビットマップ
//
//  透過状態の確認用に TListView の背景色を設定
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ImageList1.SetSize(128, 128);
  ImageList1.ColorDepth := cd8Bit;

  ListView1.Items.Clear;
  ListView1.Color := clSilver;
  ListView1.ViewStyle   := vsIcon;
  ListView1.LargeImages := ImageList1;
end;

//=============================================================================
//  32 ビット色のアルファチャンネル付きの画像を TImageList に格納
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LBitmap   : TBitmap;
  LPngImage : TPngImage;
  LIcon     : TIcon;
  LIndex    : Integer;
begin
  ListView1.Items.Clear;
  ImageList1.Clear;

  LBitmap := TBitmap.Create;
  try
    // 32 ビットのアルファチャンネル付きビットマップ
    LBitmap.LoadFromFile('..\Images\images_32bit.bmp');
    ImageList1.Add(LBitmap, nil);
  finally
    FreeAndNil(LBitmap);
  end;

  LBitmap   := TBitmap.Create;
  LPngImage := TPngImage.Create;
  try
    // 32 ビットの PNG 形式画像
    LPngImage.LoadFromFile('..\Images\images_32bit.png');
    LBitmap.Assign(LPngImage);
    ImageList1.Add(LBitmap, nil);
  finally
    FreeAndNil(LBitmap);
    FreeAndNil(LPngImage);
  end;

  LIcon := TIcon.Create;
  try
    // 32 ビットのアイコン画像
    LIcon.LoadFromFile('..\Images\Images_32bIT.ico');
    ImageList1.AddIcon(LIcon);
  finally
    FreeAndNil(LIcon);
  end;


  // TListView に TImageList の画像を描画
  for LIndex := 0 to ImageList1.Count - 1 do begin
    ListView1.Items.Add.Caption := 'Image - ' + IntToStr(LIndex);
    ListView1.Items[LIndex].ImageIndex := LIndex;
  end;
end;

//=============================================================================
//  24 ビット色以下の画像を読み込んで TImageList に格納
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LBitmap     : TBitmap;
  LMaskBitmap : TBitmap;
  LGifImage   : TGIFImage;
  LIcon       : TIcon;
  LIndex      : Integer;
begin
  ListView1.Items.Clear;
  ImageList1.Clear;

  LBitmap     := TBitmap.Create;
  LMaskBitmap := TBitmap.Create;
  try
    // 24 ビット色のビットマップ画像
    LBitmap.LoadFromFile('..\Images\simple_24bit.bmp');

    LMaskBitmap.Assign(LBitmap);
    LMaskBitmap.Mask(LBitmap.TransparentColor);
    ImageList1.Add(LBitmap, LMaskBitmap);
  finally
    FreeAndNil(LBitmap);
    FreeAndNil(LMaskBitmap);
  end;

  LBitmap     := TBitmap.Create;
  LMaskBitmap := TBitmap.Create;
  LGifImage   := TGIFImage.Create;
  try
    // GIF 形式の画像 ( 256 色 )
    LGifImage.LoadFromFile('..\Images\Simple_8bit.gif');
    LBitmap.SetSize(LGifImage.Width, LGifImage.Height);

    LGifImage.Transparent := False;
    LBitmap.Canvas.Draw(0, 0, LGifImage);
    LMaskBitmap.Assign(LBitmap);
    LMaskBitmap.Mask(LGifImage.Bitmap.TransparentColor);
    ImageList1.Add(LBitmap, LMaskBitmap);
  finally
    FreeAndNil(LBitmap);
    FreeAndNil(LMaskBitmap);
    FreeAndNil(LGifImage);
  end;

  LIcon := TIcon.Create;
  try
    // 24 ビット色のアイコン画像
    LIcon.LoadFromFile('..\Images\Images_24bIt.ico');
    ImageList1.AddIcon(LIcon);

    // 8 ビット色のアイコン画像
    LIcon.LoadFromFile('..\Images\Images_8bIt.ico');
    ImageList1.AddIcon(LIcon);
  finally
    FreeAndNil(LIcon);
  end;


  // TListView に TImageList の画像を描画
  for LIndex := 0 to ImageList1.Count - 1 do begin
    ListView1.Items.Add.Caption := 'Image - ' + IntToStr(LIndex);
    ListView1.Items[LIndex].ImageIndex := LIndex;
  end;
end;

end.




07_TListView における画像間のスペース


TListView.ViewStyle の値を vsIcon にして画像を描画した場合,各画像の間にはスペースがあります.Item 間の間隔,スペースとも言えます.下図はそれを確認した結果です.描画している画像のサイズは 128 x 128 です.枠線のサイズも同じ 128 x 128 です.




図12
デフォルトの画像の描画間隔

この画像間のスペースを,ListView_SetIconSpacing 関数を使用して変更した結果です.




図13
画像の描画間隔を変更

リスト7
TListView における画像間のスペース
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ImgList, Vcl.ComCtrls,
  Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ImageList1: TImageList;
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    procedure SetImageSpace;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  Winapi.CommCtrl;

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  ImageList1.SetSize(128, 128);
  ImageList1.ColorDepth := cd32Bit;

  ListView1.Items.Clear;
  ListView1.ViewStyle   := vsIcon;
  ListView1.LargeImages := ImageList1;
end;

//=============================================================================
//  32 ビット色のビットマップ画像を TImageList iに格納
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LBitmap : TBitmap;
  LIndex  : Integer;
begin
  SetImageSpace;

  ListView1.Items.Clear;
  ImageList1.Clear;

  LBitmap := TBitmap.Create;
  try
    // 128 x128 の四角形の画像を読み込む ( 32 ビット色 )
    LBitmap.LoadFromFile('..\Images\Frame_32bit.bmp');

    // それを TImageList に格納
    ImageList1.Add(LBitmap, nil);
    ImageList1.Add(LBitmap, nil);
    ImageList1.Add(LBitmap, nil);
    ImageList1.Add(LBitmap, nil);
    ImageList1.Add(LBitmap, nil);
    ImageList1.Add(LBitmap, nil);
  finally
    FreeAndNil(LBitmap);
  end;


  // TListView に TImageList の画像を描画
  for LIndex := 0 to ImageList1.Count - 1 do begin
    ListView1.Items.Add.Caption := 'Image - ' + IntToStr(LIndex);
    ListView1.Items[LIndex].ImageIndex := LIndex;
  end;
end;

//-----------------------------------------------------------------------------
//  TListView での画像描画の間隔を変更
//  uses に Winapi.CommCtrl が必要
//-----------------------------------------------------------------------------
procedure TForm1.SetImageSpace;
{$WRITEABLECONST ON}
const
  LImgFlag : Boolean = False;
{$WRITEABLECONST OFF}
var
  LWidth  : WORD;
  LHeight : WORD;
begin
  // トグル動作
  if LImgFlag then begin
    LWidth  := ImageList1.Width + 25;
    LHeight := ImageList1.Height + 25;
  end else begin
    // デフォルトの設定値
    LWidth  := WORD(-1);
    LHeight := WORD(-1);
  end;
  LImgFlag := not LImgFlag;

  // 画像の描画間隔 ( スペース ) を設定
  ListView_SetIconSpacing(ListView1.Handle, LWidth, LHeight);
end;

end.