Delphi Programming / Object Pascal Delphi サンプルプログラム集  
           
        
        
        
          
            
              914_256 色のビットマップと TGifImage.Bitmap のピクセル操作  
            
               動作確認等  
              Windows 7 U64(SP1) + Delphi XE(UP1) Pro  
           
        
        
          
            
               914_256Biamp_TGifImage.zip [5,264 KB] 2018年01月11日版 (EXE 同梱)  
             
           
        
        
          
            
               256 色ビットマップと TGIFImage.Bitmap のピクセル操作 
             
           
        
        
          
            
              
                  ビット深さ 8 (256 色) のビットマップのピクセル操作に関するテストプログラムです.
                
                
                  8 ビット以下のビットマップの各ピクセルの値は,ピクセルの色の値ではありません.ピクセルの値はパレットのインデックスです.パレットというのは,色の情報を格納したテーブルのことです.
                
                  256 色の以下のビットマップのピクセルデータは,
                
                
                  8 ビットのビットマップでは,8 ビットでパレットのインデックスの値 
                  4 ビットのビットマップでは,4 ビットでパレットのインデックスの値 
                  2 ビットのビットマップでは,2 ビットでパレットのインデックスの値 
                  1 ビットのビットマップでは,1 ビットでパレットのインデックスの値 
                 
                
                  が割り当てられています.256 色以下のビットマップの縦と横のサイズの,内部での値は 4 の倍数になります.4 の倍数でない残りのピクセルはデータのない領域となります.
                
                
                  このことから,256 未満のビットマップのピクセル操作は面倒だと言えます.
                
                  24 ビットと 32 ビットのビットマップには,パレット情報はありません.24 ビット,32 ビットのビットマップのピクセルの値は色の値です.
                
 
           
        
        
          
            
              
                  元のビットマップ画像と同じビットマップ画像を複製するだけであれば,以下のように,Assign で代入するとか,DestBitmap の Canvas に Draw メソッド等で描画すれば十分です.本ページのサンプルコードは必要ありません.
 
           
        
        copy code 
procedure  TForm1.Button1Click(Sender: TObject);var LSrcBitmap : TBitmap; 
  LDstBitmap : TBitmap; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcBitmap := TBitmap.Create; 
  LDstBitmap := TBitmap.Create; 
  try // 256色のビットマップ画像を読み込むLSrcBitmap.LoadFromFile('503.bmp' ); 
    // DstBitmapに元のビットマップを代入// DstBitmapも8ビットとなるLDstBitmap.Assign(LSrcBitmap); 
    // 両方のビットマップをTIamgeに描画Image1.Picture.Assign(LSrcBitmap); 
    Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcBitmap); 
    FreeAndNil(LDstBitmap); 
  end ;end ; 
        
          
            
              
                  [備考 1]
                 
           
        
        
          
            
              
                  [備考 2]
 
           
        
        
          
            
              01_ 256 色ビットマップのピクセル操作  -  パレット設定なし 
           
        
        
          
            
              
                  次の処理を行うサンプルです.
                
                
                  ディスクから 8 ビットのビットマップを読み込む 
                  新規に 8  ビットのビットマップを作成する 
                  新規に作成したビットマップに,元のビットマップのデータを転送する 
                  元のビットマップと処理したビットマップを,比較のため TImage に表示する 
                 
                
                  上で書いたように,ピクセルの値はパレットのインデックスです.
                
                  以下の結果の図から分かるように,元の色が反映されていません.
 
           
        
        
          
            
              図1  
            
              図2  
            
              図3  
           
        
        
          
            
              リスト1  
           
        
copy code 
unit  Unit1;interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, ExtCtrls; 
type TForm1 = class (TForm) 
    Image1: TImage; 
    Button1: TButton; 
    Button2: TButton; 
    Image2: TImage; 
    procedure  Button1Click(Sender: TObject);procedure  Button2Click(Sender: TObject);private { Private 宣言 } public { Public 宣言 } end ;var Form1: TForm1; 
implementation {$R *.dfm} // =============================================================================//   8ビット(256色)ビットマップの,ピクセル操作による転送例//   元のビットマップはScanLineで,転送先はTCanvas.Pixelsで色を代入//   パレットの指定がない場合// //   ビットマップのパレットの指定がないとデフォルトのパレットが使用される// =============================================================================procedure  TForm1.Button1Click(Sender: TObject);var LSrcBitmap    : TBitmap; 
  LDstBitmap    : TBitmap; 
  LSrcScanArray : PByteArray; 
  LPosX         : Integer; 
  LPosY         : Integer; 
  LPalColor     : Cardinal; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcBitmap := TBitmap.Create; 
  LDstBitmap := TBitmap.Create; 
  try // 256色のビットマップ画像を読み込んでTImageに表示LSrcBitmap.LoadFromFile('503.bmp' ); 
    Image1.Picture.Assign(LSrcBitmap); 
    // 256色のビットマップを生成LDstBitmap.PixelFormat := pf8bit; 
    LDstBitmap.Width       := LSrcBitmap.Width; 
    LDstBitmap.Height      := LSrcBitmap.Height; 
    // ピクセル操作でコピーfor  LPosY := 0  to  LSrcBitmap.Height - 1  do  begin LSrcScanArray := LSrcBitmap.ScanLine[LPosY]; 
      for  LPosX := 0  to  LSrcBitmap.Width - 1  do  begin LPalColor := PALETTEINDEX(LSrcScanArray[LPosX]); 
        LDstBitmap.Canvas.Pixels[LPosX, LPosY] := LPalColor; 
      end ;end ;Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcBitmap); 
    FreeAndNil(LDstBitmap); 
  end ;end ;// =============================================================================//   8ビット(256色)ビットマップの,ピクセル操作による転送例//   元のビットマップも転送先もScanLineで操作//   パレットの指定がない場合// //   ビットマップのパレットの指定がないとデフォルトのパレットが使用される// =============================================================================procedure  TForm1.Button2Click(Sender: TObject);var LSrcBitmap     : TBitmap; 
  LDstBitmap     : TBitmap; 
  LSrcScanArray  : PByteArray; 
  LDstScanArray  : PByteArray; 
  LPosX          : Integer; 
  LPosY          : Integer; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcBitmap := TBitmap.Create; 
  LDstBitmap := TBitmap.Create; 
  try // 256色のビットマップ画像を読み込んでTImageに表示LSrcBitmap.LoadFromFile('503.bmp' ); 
    Image1.Picture.Assign(LSrcBitmap); 
    // 256色のビットマップを生成LDstBitmap.PixelFormat := pf8bit; 
    LDstBitmap.Width       := LSrcBitmap.Width; 
    LDstBitmap.Height      := LSrcBitmap.Height; 
    // ピクセル操作でコピーfor  LPosY := 0  to  LSrcBitmap.Height - 1  do  begin LSrcScanArray := LSrcBitmap.ScanLine[LPosY]; 
      LDstScanArray := LDstBitmap.ScanLine[LPosY]; 
      for  LPosX := 0  to  LSrcBitmap.Width - 1  do  begin LDstScanArray[LPosX] := LSrcScanArray[LPosX]; 
      end ;end ;Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcBitmap); 
    FreeAndNil(LDstBitmap); 
  end ;end ;end . 
        
          
            
              
                  前項のサンプルで,転送先のビットマップのパレットとして使用されたのは,システム既定のパレットです.このパレットは,GetSystemPaletteEntries を使用して取得できます.
                
                  新規に 256 色以下のビットマップを生成すると,自動的にシステム既定のパレットが使用されます.したがって,実際には改めてシステムパレットに設定する必要はありません.
                
 
           
        
        
          
            
              図4  
            
              図5  
            
              図6  
           
        
        
          
            
              リスト2  
           
        
copy code 
unit  Unit1;interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, ExtCtrls; 
type TForm1 = class (TForm) 
    Button1: TButton; 
    Image1: TImage; 
    Button2: TButton; 
    procedure  Button1Click(Sender: TObject);procedure  Button2Click(Sender: TObject);private { Private 宣言 } procedure  DrawPalleteColor(OutImage: TImage; TargetBmp: TBitmap;RectSize: Integer); 
  public { Public 宣言 } end ;var Form1: TForm1; 
implementation {$R *.dfm} // -----------------------------------------------------------------------------//   システムのデフォルト(既定)のパレットを取得する関数//   Colors : 16 or 256// -----------------------------------------------------------------------------function  GetDesktopPalette(Colors: Cardinal): HPALETTE;var LLogPal : TMaxLogPalette; 
  LScrDC  : HDC; 
begin LLogPal.palVersion    := $300 ; 
  LLogPal.palNumEntries := Colors; 
  LScrDC := GetDC(0 ); 
  try if  GetSystemPaletteEntries(LScrDC, 0 , Colors, LLogPal.palPalEntry) > 0  then  begin Result := CreatePalette(pLogPalette(@LLogPal)^); 
    end  else  begin Result := 0 ; 
    end ;finally ReleaseDC(0 , LScrDC); 
  end ;end ;// =============================================================================//   ビットマップのパレット表示 256色// =============================================================================procedure  TForm1.Button1Click(Sender: TObject);var LSrcBmp : TBitmap; 
begin Image1.Picture.Assign(nil ); 
  LSrcBmp := TBitmap.Create; 
  try LSrcBmp.PixelFormat := pf8bit; 
    LSrcBmp.Width       := 40 ; 
    LSrcBmp.Height      := 40 ; 
    // システムの既定の256色のパレットにするLSrcBmp.Palette := GetDesktopPalette(256 ); 
    DrawPalleteColor(Image1, LSrcBmp, 15 ); 
  finally FreeAndNil(LSrcBmp); 
  end ;end ;// =============================================================================//   ビットマップのパレット表示 16色// =============================================================================procedure  TForm1.Button2Click(Sender: TObject);var LSrcBmp : TBitmap; 
begin Image1.Picture.Assign(nil ); 
  LSrcBmp := TBitmap.Create; 
  try LSrcBmp.PixelFormat := pf4bit; 
    LSrcBmp.Width       := 40 ; 
    LSrcBmp.Height      := 40 ; 
    // システムの既定の16色のパレットにするLSrcBmp.Palette := GetDesktopPalette(16 ); 
    DrawPalleteColor(Image1, LSrcBmp, 15 ); 
  finally FreeAndNil(LSrcBmp); 
  end ;end ;// -----------------------------------------------------------------------------//   OoutImage(TImage)にTargetBmp(TBitmap)のパレットの色を描画するメソッド//   RectSizeは描画する矩形のサイズ// -----------------------------------------------------------------------------procedure  TForm1.DrawPalleteColor(OutImage: TImage; TargetBmp: TBitmap;RectSize: Integer); 
var LPosY        : Integer; 
  LPosX        : Integer; 
  ALeft        : Integer; 
  LTop         : Integer; 
  LCntVertRect : Integer; 
  LCntHorzRect : Integer; 
  LIndex       : Integer; 
begin if  TargetBmp.PixelFormat = pf4bit then  begin LCntHorzRect := 4 ; 
    LCntVertRect := 4 ; 
  end  else if  TargetBmp.PixelFormat = pf8bit then  begin LCntHorzRect := 16 ; 
    LCntVertRect := 16 ; 
  end  else  begin exit; 
  end ;OutImage.Picture.Assign(nil ); 
  OutImage.Width  := LCntHorzRect * RectSize - LCntHorzRect + 1 ; 
  OutImage.Height := LCntVertRect * RectSize - LCntVertRect + 1 ; 
  OutImage.Canvas.Pen.Width :=0 ; 
  OutImage.Canvas.Pen.Color :=clBlack; 
  SelectPalette(OutImage.Canvas.Handle, TargetBmp.Palette, False); 
  RealizePalette(OutImage.Canvas.Handle); 
  LTop := 0 ; 
  // 縦方向はfor  LPosY := 0  to  LCntVertRect - 1  do  begin ALeft := 0 ; 
    for  LPosX := 0  to  LCntHorzRect - 1  do  begin LIndex := LCntHorzRect * LPosY + LPosX; 
      OutImage.Canvas.Brush.Color := PALETTEINDEX(LIndex); 
      OutImage.Canvas.Rectangle(ALeft, LTop, ALeft + RectSize, LTop + RectSize ); 
      Inc( ALeft, RectSize - 1 ); 
    end ;Inc( LTop, RectSize - 1 ); 
  end ;end ;end . 
        
          
            
              03_ 256 色ビットマップのピクセル操作  -  パレット設定あり 
           
        
        
          
            
              
                  システム既定のパレットを使用したのでは,元のビットマップと違った配色になってしまいます.
 
           
        
        
    DstBitmap.Palette := SrcBitmap.Palette; 
 
        
          
            
              
                  結果は,下図の通り,元の画像と同じになっています.
                
 
           
        
        
          
            
              図7  
            
              図8  
           
        
        
          
            
              リスト3  
           
        
copy code 
unit  Unit1;interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, ExtCtrls; 
type TForm1 = class (TForm) 
    Image1: TImage; 
    Button1: TButton; 
    Button2: TButton; 
    Image2: TImage; 
    procedure  Button1Click(Sender: TObject);procedure  Button2Click(Sender: TObject);private { Private 宣言 } public { Public 宣言 } end ;var Form1: TForm1; 
implementation {$R *.dfm} // =============================================================================//   8ビット(256色)ビットマップの転送例//   元のビットマップはScanLineで,転送先はTCanvas.Pixelsで色を代入//   転送先のパレットを元のビットマップのパレットと同じにする場合// =============================================================================procedure  TForm1.Button1Click(Sender: TObject);var LSrcBitmap    : TBitmap; 
  LDstBitmap    : TBitmap; 
  LSrcScanArray : PByteArray; 
  LPosX         : Integer; 
  LPosY         : Integer; 
  LPalColor     : Cardinal; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcBitmap := TBitmap.Create; 
  LDstBitmap := TBitmap.Create; 
  try // 256色のビットマップ画像を読み込んでTImageに表示LSrcBitmap.LoadFromFile('503.bmp' ); 
    Image1.Picture.Assign(LSrcBitmap); 
    // 256色のビットマップを生成LDstBitmap.PixelFormat := pf8bit; 
    LDstBitmap.Width       := LSrcBitmap.Width; 
    LDstBitmap.Height      := LSrcBitmap.Height; 
    // 転送先のビットマップのパレットを,転送元のパレットと同じにするLDstBitmap.Palette := LSrcBitmap.Palette; 
    // ピクセル操作でコピーfor  LPosY := 0  to  LSrcBitmap.Height - 1  do  begin LSrcScanArray := LSrcBitmap.ScanLine[LPosY]; 
      for  LPosX := 0  to  LSrcBitmap.Width - 1  do  begin LPalColor := PALETTEINDEX(LSrcScanArray[LPosX]); 
        LDstBitmap.Canvas.Pixels[LPosX, LPosY] := LPalColor; 
      end ;end ;Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcBitmap); 
    FreeAndNil(LDstBitmap); 
  end ;end ;// =============================================================================//   8ビット(256色)ビットマップの転送例//   元のビットマップも転送先もScanLineで操作//   転送先のパレットを元のビットマップのパレットと同じにする場合// //   パレットのインデックスの代入なのでそのまま代入すればよい// =============================================================================procedure  TForm1.Button2Click(Sender: TObject);var LSrcBitmap    : TBitmap; 
  LDstBitmap    : TBitmap; 
  LSrcScanArray : PByteArray; 
  LDstScanArray : PByteArray; 
  LPosX         : Integer; 
  LPosY         : Integer; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcBitmap := TBitmap.Create; 
  LDstBitmap := TBitmap.Create; 
  try // 256色のビットマップ画像を読み込んでTImageに表示LSrcBitmap.LoadFromFile('503.bmp' ); 
    Image1.Picture.Assign(LSrcBitmap); 
    // 256色のビットマップを生成LDstBitmap.PixelFormat := pf8bit; 
    LDstBitmap.Width       := LSrcBitmap.Width; 
    LDstBitmap.Height      := LSrcBitmap.Height; 
    // 転送先のビットマップのパレットを,転送元のパレットと同じにするLDstBitmap.Palette := LSrcBitmap.Palette; 
    // ピクセル操作でコピーfor  LPosY := 0  to  LSrcBitmap.Height - 1  do  begin LSrcScanArray := LSrcBitmap.ScanLine[LPosY]; 
      LDstScanArray := LDstBitmap.ScanLine[LPosY]; 
      for  LPosX := 0  to  LSrcBitmap.Width - 1  do  begin LDstScanArray[LPosX] := LSrcScanArray[LPosX]; 
      end ;end ;Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcBitmap); 
    FreeAndNil(LDstBitmap); 
  end ;end ;end . 
        
          
            
              04_ 256 色ビットマップのピクセル操作  -  パレットの操作例 
           
        
        
          
            
              
                  パレットの色を変更すれば,ビットマップの色も変わります.そのテストです.
                
                
                  新規作成したビットマップのパレットを,元のビットマップのパレットと同じにする 
                  GetPaletteEntries 関数で,そのパレットのエントリを取得する 
                  指定した範囲のパレットインデックスのエントリに,色の値をセットする 
                  CreatePalette 関数でそのパレットを転送先のパレットに設定する 
                 
                
                  という手順で行います.下図がその結果です.
                
 
           
        
        
          
            
              図9  
           
        
        
          
            
              リスト4  
           
        
copy code 
unit  Unit1;interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, ExtCtrls; 
type TForm1 = class (TForm) 
    Image1: TImage; 
    Button1: TButton; 
    Image2: TImage; 
    procedure  Button1Click(Sender: TObject);private { Private 宣言 } public { Public 宣言 } end ;var Form1: TForm1; 
implementation {$R *.dfm} // =============================================================================//   8ビット(256色)ビットマップの,ピクセル操作による転送例//   元のビットマップも転送先もScanLineで操作// //   転送先のビットマップのパレットの色を変更する操作の例// =============================================================================procedure  TForm1.Button1Click(Sender: TObject);var LSrcBitmap    : TBitmap; 
  LDstBitmap    : TBitmap; 
  LSrcScanArray : PByteArray; 
  LDstScanArray : PByteArray; 
  LPosX         : Integer; 
  LposY         : Integer; 
  LLogPal       : TMaxLogPalette; 
  LCntEntry     : WORD; 
  LPalIndex     : Byte; 
  LReffColor    : Cardinal; 
  LIndex        : Integer; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcBitmap := TBitmap.Create; 
  LDstBitmap := TBitmap.Create; 
  try // 256色のビットマップを読み込んでTImageに表示LSrcBitmap.LoadFromFile('503.bmp' ); 
    Image1.Picture.Assign(LSrcBitmap); 
    // 256色のビットマップを生成LDstBitmap.PixelFormat := pf8bit; 
    LDstBitmap.Width       := LSrcBitmap.Width; 
    LDstBitmap.Height      := LSrcBitmap.Height; 
    // 転送先のビットマップのパレットは,元のビットマップのパレットと同じにするLDstBitmap.Palette := LSrcBitmap.Palette; 
    // 転送先のビットマップのパレットのエントリを取得LLogPal.palVersion    := $300 ; 
    LLogPal.palNumEntries := 256 ; 
    GetPaletteEntries(LDstBitmap.Palette, 0 , 256 , LLogPal.palPalEntry); 
    LCntEntry := LLogPal.palNumEntries; 
    LReffColor := clWebDarkCyan; 
    // 指定範囲のインデックスのパレットの色を指定の色に変更してみるfor  LIndex := 160  to  190  do  begin LPalIndex  := Byte(LIndex); 
      if  LPalIndex <= LCntEntry then  begin LLogPal.palPalEntry[LPalIndex].peRed   := GetRValue(LReffColor); 
        LLogPal.palPalEntry[LPalIndex].peGreen := GetGValue(LReffColor); 
        LLogPal.palPalEntry[LPalIndex].peBlue  := GetBValue(LReffColor); 
        LLogPal.palPalEntry[LPalIndex].peFlags := 0 ; 
      end ;end ;// 変更したパレットを転送先のビットマップのパレットとするLDstBitmap.Palette := CreatePalette(pLogPalette(@LLogPal)^); 
    // ピクセル操作でコピーfor  LposY := 0  to  LSrcBitmap.Height - 1  do  begin LSrcScanArray := LSrcBitmap.ScanLine[LposY]; 
      LDstScanArray := LDstBitmap.ScanLine[LposY]; 
      for  LPosX := 0  to  LSrcBitmap.Width - 1  do  begin LDstScanArray[LPosX] := LSrcScanArray[LPosX]; 
      end ;end ;Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcBitmap); 
    FreeAndNil(LDstBitmap); 
  end ;end ;end . 
        
          
            
              05_ TImage の Canvas のピクセル操作 
           
        
        
          
            
              
                  上のコードは,ビットマップのインスタンスを直接操作する例です.TImage に描画したビットマップを操作する場合は,TImage のビットマップに対する操作となります.
                
                  つまり,本サンプルは,TImage に描画した元のビットマップの色数には関係なく動作します.
                
 
           
        
        
          
            
              図10  
           
        
        
          
            
              
                  画像以外の部分をクリックすると,下図のような結果となります.
                
                  画面上で見えている色を取得するには,例えば,以下のリンクの記事のように,画面 (スクリーン) のデバイスコンテキストを使用します.
                
 
           
        
        
          
            
              図11 
                  この画像 (ビットマップ) は.透過表示している 
                  見えている色ではなく,実際の背景色が検出される 
                  
            
              図12 
                  この部分は,何も描画されていない 
                  何も描画されていない部分は「黒」 
                  
           
        
        
          
            
              リスト5  
           
        
copy code 
// =============================================================================//   256色(8ビット)のビットマップを読み込んでTImageに表示// =============================================================================procedure  TForm1.Button1Click(Sender: TObject);var LSrcBitmap : TBitmap; 
begin Image1.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  LSrcBitmap := TBitmap.Create; 
  try // 256色のビットマップ画像を読み込んでTImageに表示LSrcBitmap.LoadFromFile('503.bmp' ); 
    Image1.Picture.Assign(LSrcBitmap); 
  finally FreeAndNil(LSrcBitmap); 
  end ;end ;// =============================================================================//   Image1のOnMouseDownイベント処理//   マウスボタンを押下した位置の色の値を取得して,その色を表示// =============================================================================procedure  TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); 
var LColor : Cardinal; 
begin Panel1.Caption := '' ; 
  Panel2.Caption := '' ; 
  Panel1.ParentBackground := False; 
  Panel2.ParentBackground := False; 
  if  Assigned(Image1.Picture.Bitmap) then  begin // LColor := Image1.Picture.Bitmap.Canvas.Pixels[X, Y];でも同じLColor := Image1.Canvas.Pixels[X, Y]; 
    Panel1.Caption := Format('$%.8x' , [LColor]); 
    Panel2.Color   :=  LColor; 
  end ;end ; 
        
          
            
              
                  次のコードは,マウスボタン押下位置のピクセルの色を変更します.TImage.Canvas の Pixels プロパティに色の値をセットしています.画像は,Draw メソッドで TImage の Canvas に描画しています.
                
                  上のコードのように,Assign メソッドや LoadFromXXX メソッド で描画した場合は,読み込んだビットマップが TImage のビットマップとなります.Assign や LoadFromXXX による描画は,主に画像の表示だけが目的の場合に使用されます.
                
                  TImage 内部のビットマップは,何も描画していない状態では,その大きさは 0 です.TImage の Canvas に何かを描画すると,TImage と同じ大きさとなり,背景が「白」で塗り潰されます.この TImage のビットマップは 32 ビットです.
                
                  TImage に描画した複数のビットマップ画像を個別に取り出せないか,という質問を以前見たことがあります.描画した画像は,TImage 内部のビットマップに描画して,1 つのビットマップ (画像) となっています.したがって,描画前の画像として,各々を個別に取り出すことはできません.
 
           
        
        
          
            
              図13  
            
              図14  
           
        
        
          
            
              リスト6  
           
        
copy code 
// =============================================================================//   256色(8ビット)のビットマップを読み込んでTImageに表示//   TImageのCanvasに,読み込んだビットマップを描画// =============================================================================procedure  TForm1.Button1Click(Sender: TObject);var LSrcBitmap : TBitmap; 
begin Image1.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  LSrcBitmap := TBitmap.Create; 
  try // 256色のビットマップ画像を読み込むLSrcBitmap.LoadFromFile('503.bmp' ); 
    LSrcBitmap.Transparent := True; 
    // Image1に描画する// Image1.Picture.Assign(LSrcBitmap);ではなくDrawを使用するImage1.Canvas.Draw(0 , 0 , LSrcBitmap); 
  finally FreeAndNil(LSrcBitmap); 
  end ;end ;// =============================================================================//   Image1のOnMouseDownイベント処理//   マウスボタンを押下した位置の色を,指定の色に変更する// =============================================================================procedure  TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); 
begin if  Assigned(Image1.Picture.Bitmap) then  begin // Image1.Picture.Bitmap.Canvas.Pixels[X, Y] := clRed;でも同じImage1.Canvas.Pixels[X, Y] := clRed; 
  end ;end ; 
        
          
            
              
                  TImage のビットマップは,何も描画していない状態では,そのサイズは 0 です.したがって,下のコードを実行しても,画像は描画されません.
 
           
        
        copy code 
        
procedure  TForm1.Button1Click(Sender: TObject);var LSrcBitmap : TBitmap; 
begin SrcBitmap := TBitmap.Create; 
  try SrcBitmap.LoadFromFile('503.bmp' ); 
    // 描画するImage1.Picture.Bitmap.Canvas.Draw(0 , 0 , LSrcBitmap); 
  finally FreeAndNil(LSrcBitmap); 
  end ;end ; 
 
        
          
            
              06_ TGifImage.Bitmap のピクセル操作 
           
        
        
          
            
              
                  GIF は,最大 256 色のビットマップを複数格納できる形式です.以下のコードは画像が 1 つだけの場合です.
                
                
                  TGifImage の場合は,TGifImage.Bitmap の Canvas の Pixels プロパティ,あるいは ScanLine で取得した配列から,該当するピクセルの色の値を取得することができます.この色の値は,32 ビットのビットマップと同じ 4 バイトです.
                
                  Button1 クリックでは,元のビットマップのピクセルデータを Scnaline で取り出し,ScanLine で取得した転送先のビットマップのピクセルにデータを代入します.
                
                  Delphi 2006 以前で GIF 画像を扱うには,[912] [07_ VCLImageUtils を使用したビットマップ画像のグレイスケール化] の記事を参考にしてください.
                
 
           
        
        
          
            
              図15  
            
              図16  
            
              図17  
           
        
        
          
            
              リスト7  
           
        
copy code 
unit  Unit1;interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, ExtCtrls; 
type TForm1 = class (TForm) 
    Image1: TImage; 
    Button1: TButton; 
    Button2: TButton; 
    Button3: TButton; 
    Image2: TImage; 
    procedure  Button1Click(Sender: TObject);procedure  Button2Click(Sender: TObject);procedure  Button3Click(Sender: TObject);private { Private 宣言 } public { Public 宣言 } end ;var Form1: TForm1; 
implementation uses  Gifimg;{$R *.dfm} // =============================================================================//   TGifImageのBitmapのピクセルの操作例//   TGifImage.BitmapのScanLineでは,ピクセルの色情報が取得できる//   1ピクセル当たり4バイトの情報// //   ScanLineデータの格納は, Gifimg.pas内のPRGBQuadArrayを利用// =============================================================================procedure  TForm1.Button1Click(Sender: TObject);var LSrcGifImg    : TGIFImage; 
  LDstBitmap    : TBitmap; 
  LSrcScanArray : PRGBQuadArray; 
  LDstScanArray : PRGBQuadArray; 
  LPosX         : Integer; 
  LPosY         : Integer; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcGifImg := TGIFImage.Create; 
  LDstBitmap := TBitmap.Create; 
  try // GIF画像を読み込んで表示LSrcGifImg.LoadFromFile('502.gif' ); 
    Image1.Picture.Assign(LSrcGifImg); 
    // 32ビットのビットマップを生成LDstBitmap.PixelFormat := pf32bit; 
    LDstBitmap.Width  := LSrcGifImg.Width; 
    LDstBitmap.Height := LSrcGifImg.Height; 
    // ピクセル操作for  LPosY := 0  to  LSrcGifImg.Bitmap.Height - 1  do  begin LSrcScanArray := LSrcGifImg.Bitmap.ScanLine[LPosY]; 
      LDstScanArray := LDstBitmap.ScanLine[LPosY]; 
      for  LPosX := 0  to  LSrcGifImg.Bitmap.Width - 1  do  begin LDstScanArray[LPosX] := LSrcScanArray[LPosX]; 
      end ;end ;Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcGifImg); 
    FreeAndNil(LDstBitmap); 
  end ;end ;// =============================================================================//   TGifImageのBitmapのピクセルの操作例//   TGifImage.BitmapのScanLineでは,ピクセルの色情報が取得できる//   1ピクセル当たり4バイトの情報//   元の画像の中央の色と同じピクセルの色を変更する例// //   ScanLineデータの格納は, Gifimg.pas内のPRGBQuadArrayを利用// =============================================================================procedure  TForm1.Button2Click(Sender: TObject);var LSrcGifImg    : TGIFImage; 
  LDstBitmap    : TBitmap; 
  LSrcScanArray : PRGBQuadArray; 
  LDstScanArray : PRGBQuadArray; 
  LColorQuad    : RGBQUAD; 
  LPosX         : Integer; 
  LPosY         : Integer; 
  LColor        : Cardinal; 
  LXCenter      : Integer; 
  LYCenter      : Integer; 
  LReffColor    : Cardinal; 
  LChangeColor  : Cardinal; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcGifImg := TGIFImage.Create; 
  LDstBitmap := TBitmap.Create; 
  try // GIF画像を読み込んで表示LSrcGifImg.LoadFromFile('502.gif' ); 
    Image1.Picture.Assign(LSrcGifImg); 
    // 32ビットのビットマップを生成LDstBitmap.PixelFormat := pf32bit; 
    LDstBitmap.Width  := LSrcGifImg.Width; 
    LDstBitmap.Height := LSrcGifImg.Height; 
    LXCenter     := LSrcGifImg.Width  div  2 ; 
    LYCenter     := LSrcGifImg.Height div  2 ; 
    LReffColor   := LSrcGifImg.Bitmap.Canvas.Pixels[LXCenter, LYCenter]; 
    LChangeColor := clWebLightGoldenrodYellow; 
    // ピクセル操作for  LPosY := 0  to  LSrcGifImg.Bitmap.Height - 1  do  begin LSrcScanArray := LSrcGifImg.Bitmap.ScanLine[LPosY]; 
      LDstScanArray := LDstBitmap.ScanLine[LPosY]; 
      for  LPosX := 0  to  LSrcGifImg.Bitmap.Width - 1  do  begin LColorQuad := LSrcScanArray[LPosX]; 
        LColor    := RGB(LColorQuad.rgbRed, LColorQuad.rgbGreen, LColorQuad.rgbBlue); 
        if  LColor = LReffColor then  begin LColorQuad.rgbRed      := GetRValue(LChangeColor); 
          LColorQuad.rgbGreen    := GetGValue(LChangeColor); 
          LColorQuad.rgbBlue     := GetBValue(LChangeColor); 
          LColorQuad.rgbReserved := 0 ; 
          LDstScanArray[LPosX]       := LColorQuad; 
        end  else  begin LDstScanArray[LPosX] := LSrcScanArray[LPosX]; 
        end ;end ;end ;Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcGifImg); 
    FreeAndNil(LDstBitmap); 
  end ;end ;// =============================================================================//   TGifImageのBitmapのピクセルの操作例//   TGifImage.BitmapのScanLineでは,ピクセルの色情報が取得できる//   1ピクセル当たり4バイトの情報//   元の画像の中央の色と同じピクセルの色を変更する例(Pixelsプロパティを使用)// //   ScanLineデータの格納は, Gifimg.pas内のPRGBQuadArrayを利用// =============================================================================procedure  TForm1.Button3Click(Sender: TObject);var LSrcGifImg   : TGIFImage; 
  LDstBitmap   : TBitmap; 
  SrcScanArray : PRGBQuadArray; 
  LColorQuad   : RGBQUAD; 
  LPosX        : Integer; 
  LPosY        : Integer; 
  LColor       : Cardinal; 
  LXCenter     : Integer; 
  LYCenter     : Integer; 
  LReffColor   : Cardinal; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcGifImg := TGIFImage.Create; 
  LDstBitmap := TBitmap.Create; 
  try // GIF画像を読み込んで表示LSrcGifImg.LoadFromFile('502.gif' ); 
    Image1.Picture.Assign(LSrcGifImg); 
    // 32ビットのビットマップを生成LDstBitmap.PixelFormat := pf32bit; 
    LDstBitmap.Width  := LSrcGifImg.Width; 
    LDstBitmap.Height := LSrcGifImg.Height; 
    LXCenter   := LSrcGifImg.Width  div  2 ; 
    LYCenter   := LSrcGifImg.Height div  2 ; 
    LReffColor := LSrcGifImg.Bitmap.Canvas.Pixels[LXCenter, LYCenter]; 
    // ピクセル操作for  LPosY := 0  to  LSrcGifImg.Bitmap.Height - 1  do  begin SrcScanArray := LSrcGifImg.Bitmap.ScanLine[LPosY]; 
      for  LPosX := 0  to  LSrcGifImg.Bitmap.Width - 1  do  begin LColorQuad := SrcScanArray[LPosX]; 
        LColor    := RGB(LColorQuad.rgbRed, LColorQuad.rgbGreen, LColorQuad.rgbBlue); 
        if  LColor = LReffColor then  begin LDstBitmap.Canvas.Pixels[LPosX, LPosY] := clWebDarkCyan; 
        end  else  begin LDstBitmap.Canvas.Pixels[LPosX, LPosY] := LColor; 
        end ;end ;end ;Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcGifImg); 
    FreeAndNil(LDstBitmap); 
  end ;end ;end . 
        
          
            
              
                  本ページの最初に述べたように,TGifImage の場合も,元の GIF 画像からビットマップ画像をコピーするだけであれば,以下のように,Assign で代入するとか,DestBitmap の Canvas に Draw メソッド等で描画すれば十分です.
 
           
        
        
          
            
              
                  [備考]
 
           
        
        
          
            
              リスト8  
           
        
copy code 
procedure  TForm1.Button2Click(Sender: TObject);var LSrcGifImg : TGifImage; 
  LDstBitmap : TBitmap; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcGifImg := TGIFImage.Create; 
  LDstBitmap := TBitmap.Create; 
  try // 256色のGIF画像を読み込むLSrcGifImg.LoadFromFile('502.gif' ); 
    // DstBitmapに元のGIF画像を代入LDstBitmap.Assign(LSrcGifImg); 
    // pfDevice(デバイス依存のDDB形式)となるのでDIB(デバイス非依存形式)に変換LDstBitmap.PixelFormat := pf32bit; 
    // 両方の画像をTIamgeに描画Image1.Picture.Assign(LSrcGifImg); 
    Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcGifImg); 
    FreeAndNil(LDstBitmap); 
  end ;end ; 
        
          
            
              
                  転送先が 8 ビットのビットマップの場合は,例えば,次のようにします.8 ビットの場合はパレットの設定が必要です.
 
           
        
        
          
            
              リスト9  
           
        
copy code 
procedure  TForm1.Button3Click(Sender: TObject);var LSrcGifImg : TGifImage; 
  LDstBitmap : TBitmap; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcGifImg := TGIFImage.Create; 
 L DstBitmap := TBitmap.Create; 
  try // 256色のGIF画像を読み込むSrcGifImg.LoadFromFile('502.gif' ); 
    // DstBitmapに元のGIF画像を代入LDstBitmap.Assign(LSrcGifImg); 
    // pfDevice(デバイス依存のDDB形式)となるのでDIB(デバイス非依存形式)に変換LDstBitmap.PixelFormat := pf8bit; 
    // 8ビットの場合はパレットを同じにする(しないと色が正しく反映されない)LDstBitmap.Palette := LSrcGifImg.Bitmap.Palette; 
    // 両方の画像をTIamgeに描画Image1.Picture.Assign(LSrcGifImg); 
    Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcGifImg); 
    FreeAndNil(LDstBitmap); 
  end ;end ; 
        
          
            
              
                  本ページのサンプルでも,当サイトのサンプルプログラム集,あるいはネット上のサンプルでも多くの使われていますが,TColor と R (赤),G (緑), B (青) の値の相互変換の確認テストです.
                
                
                  TColor の値から R, G, B の各値を求めるには  GetRValue, GetGValue, GetBValue 関数が利用できます.その逆に R, G, B の値から TColor の値に変換するには,RGB という関数が使用できます.
 
           
        
        
          
            
              
                  下図が設計時と実行の画面です.
 
           
        
        
          
            
              COLOR Value  TColor 値の 10 進数表示 
             
            
              COLOR HEX  TColor 値の 16 進数表示 
             
            
              ColorToString  TColor 値の clWhite 等の色定数名文字列 
             
            
              ColoToIdent  TColor 値の clWhite 等の色定数名文字列 
             
            
              HTML RGB  TColor 値を 16 進数にした値.上位バイトから順に R, G, B の値 
             
            
              WebColorName  HTML 色の clWebRet 等の色定数名文字列 
             
           
        
        
          
            
              図18  
            
              図19  
            
              図20  
            
              図21  
           
        
        
          
            
              リスト10  
           
        
copy code 
unit  Unit1;interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, ExtCtrls, TeCanvas; 
type TForm1 = class (TForm) 
    ButtonColor1: TButtonColor; 
    Panel1: TPanel; 
    ScrollBar1: TScrollBar; 
    ScrollBar2: TScrollBar; 
    ScrollBar3: TScrollBar; 
    Label1: TLabel; 
    Label2: TLabel; 
    Label3: TLabel; 
    Memo1: TMemo; 
    Button1: TButton; 
    procedure  ButtonColor1Click(Sender: TObject);procedure  FormShow(Sender: TObject);procedure  ScrollBar1Change(Sender: TObject);procedure  Button1Click(Sender: TObject);private { Private 宣言 } procedure  DisplayColorValues;public { Public 宣言 } end ;var Form1: TForm1; 
implementation uses  GraphUtil;{$R *.dfm} // =============================================================================//   フォーム表示開始時の処理// =============================================================================procedure  TForm1.FormShow(Sender: TObject);begin // この設定がないと色は変化しないPanel1.ParentBackground := False; 
  Panel1.Caption := '' ; 
  // スクロールバーの最小値と最大値は各R,G,Bの最小値と最大値と同じにするScrollBar1.Min := 0 ; 
  ScrollBar1.Max := 255 ; 
  ScrollBar2.Min := 0 ; 
  ScrollBar2.Max := 255 ; 
  ScrollBar3.Min := 0 ; 
  ScrollBar3.Max := 255 ; 
  // R,G,Bの値を表示するTLabelの文字の色Label1.Font.Color := clRed; 
  Label2.Font.Color := RGB(0 , $AF , 0 ); 
  Label3.Font.Color := clBlue; 
  Label1.Font.Style := [fsBold]; 
  Label2.Font.Style := [fsBold]; 
  Label3.Font.Style := [fsBold]; 
  // 初期状態の色ScrollBar1.Position := 255 ; 
  ScrollBar2.Position := 255 ; 
  ScrollBar3.Position := 255 ; 
  Button1.Visible := False; 
end ;// =============================================================================//   Memo1に色の値を表示// =============================================================================procedure  TForm1.Button1Click(Sender: TObject);var LColor   : TColor; 
  LRValue  : Byte; 
  LGValue  : Byte; 
  LBValue  : Byte; 
  LIndent  : String ; 
  LStrHTML : string ; 
begin Memo1.Lines.Clear; 
  Memo1.Lines.BeginUpdate; 
  LColor := Panel1.Color; 
  Memo1.Lines.Add('COLOR Value   : '  + IntToStr(LColor)); 
  Memo1.Lines.Add('COLOR HEX     : $'  + IntToHex(LColor, 8 )); 
  Memo1.Lines.Add('ColorToString : '  + ColorToString(LColor)); 
  ColorToIdent(LColor, LIndent); 
  Memo1.Lines.Add('ColoToIdent   : '  + LIndent); 
  LRValue  := GetRValue(LColor); 
  LGValue  := GetGValue(LColor); 
  LBValue  := GetBValue(LColor); 
  LStrHTML := Format('#%.2x%.2x%.2x' , [LRValue, LGValue, LBValue]); 
  Memo1.Lines.Add('HTML RGB      : '  +  LStrHTML); 
  Memo1.Lines.Add('WebColorName  : '  + ColorToWebColorName(LColor)); 
  ButtonColor1.SymbolColor := LColor; 
  Memo1.Lines.EndUpdate; 
end ;// =============================================================================//   カラーダイアログを表示して色を設定//   TColorの値をR,G,Bの各値に変換(分解)する例// //    TButtonColorは[TeeChartStd]タブにあるTTCharrのコンポーネント// =============================================================================procedure  TForm1.ButtonColor1Click(Sender: TObject);var LRValue : Byte; 
  LGValue : Byte; 
  LBValue : Byte; 
begin // カラーダイアログで設定した値を設定した色の値とするPanel1.Color := ButtonColor1.SymbolColor; 
  // TColorの値からR,G,Bの値を取得LRValue := GetRValue(Panel1.Color); 
  LGValue := GetGValue(Panel1.Color); 
  LBValue := GetBValue(Panel1.Color); 
  // TScrollBarの位置を各R,G,Bの値と同じにするScrollBar1.Position := LRValue; 
  ScrollBar2.Position := LGValue; 
  ScrollBar3.Position := LBValue; 
  DisplayColorValues; 
  Button1Click(nil ); 
end ;// =============================================================================//   ScrollBar1のOnChangeイベント処理//   R,G,Bの各値からTColorを取得する例// //   ScrollBar1,ScrollBar2,ScrollBar3共有イベント// =============================================================================procedure  TForm1.ScrollBar1Change(Sender: TObject);var LRValue : Byte; 
  LGValue : Byte; 
  LBValue : Byte; 
begin // 各ScrollBoxの値をR,G,Bの値とするLRValue := ScrollBar1.Position; 
  LGValue := ScrollBar2.Position; 
  LBValue := ScrollBar3.Position; 
  // R,G,Bの各値からTColorの値を取得する// 戻り値はCOLORREF(符号なし32ビット整数)// TColorでキャストしなくてもTColorの値として取得可能Panel1.Color := RGB(LRValue, LGValue, LBValue); 
  DisplayColorValues; 
  Button1Click(nil ); 
end ;// -----------------------------------------------------------------------------//   各R(赤),G(緑),B(青)の値をTLabelに表示する// -----------------------------------------------------------------------------procedure  TForm1.DisplayColorValues;begin Label1.Caption := Format('%3d' , [ScrollBar1.Position]); 
  Label2.Caption := Format('%3d' , [ScrollBar2.Position]); 
  Label3.Caption := Format('%3d' , [ScrollBar3.Position]); 
end ;end . 
        
          
            
              
                  ウィンドウ等の色は,システムカラーと呼ばれる色となっています.
                
                  この設定は Windwos 8, 8.1 にはありません.変更するにはレジストリの操作が必要です.
                
 
           
        
        
          
            
               %SystemRoot%\System32\control.exe COLOR 
             
           
        
        
          
            
              図22 
                  Windwos 8, 8.1 にはない 
                  ここでの設定色はシステムカラーと呼ばれる 
                  
           
        
        
          
            
              
                  これらの定数名で色を設定すると,Windows のバージョンや,システム関係の色を変更すると変わってしまいます.そこで,これらの値と色を確認するプログラムを作成してみました.
                
                
                  これらの色は,SetSysColors 関数で設定できます.[S02] [01-01_デスクトップの背景色の変更] に設定のサンプルがあります.システムカラーの Windwos の色定数の説明は,MSDN の GetSysColor 関数の記事に一覧があります.
                
 
           
        
        
          
            
              図23  
           
        
        
          
            
              リスト11  
           
        
copy code 
unit  Unit1;interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls, ExtCtrls; 
type TForm1 = class (TForm) 
    Panel1: TPanel; 
    ListBox1: TListBox; 
    procedure  FormShow(Sender: TObject);procedure  ListBox1Click(Sender: TObject);private { Private 宣言 } public { Public 宣言 } end ;var Form1: TForm1; 
implementation {$R *.dfm} // =============================================================================//   フォーム表示開始時の処理//   TListBoxにシステムカラーの値をセット//   値は,Delphi XE(UP1)のGraphics.pasで定義されているもの// =============================================================================procedure  TForm1.FormShow(Sender: TObject);begin // この設定がないと色は変化しないPanel1.ParentBackground := False; 
  Panel1.Caption := '' ; 
  with  ListBox1.Items do  begin AddObject('clScrollBar' ,               TObject(clScrollBar)); 
    AddObject('clBackground' ,              TObject(clBackground)); 
    AddObject('clActiveCaption' ,           TObject(clActiveCaption)); 
    AddObject('clInactiveCaption' ,         TObject(clInactiveCaption)); 
    AddObject('clMenu' ,                    TObject(clMenu)); 
    AddObject('clWindow' ,                  TObject(clWindow)); 
    AddObject('clWindowFrame' ,             TObject(clWindowFrame)); 
    AddObject('clMenuText' ,                TObject(clMenuText)); 
    AddObject('clWindowText' ,              TObject(clWindowText)); 
    AddObject('clCaptionText' ,             TObject(clCaptionText)); 
    AddObject('clActiveBorder' ,            TObject(clActiveBorder)); 
    AddObject('clInactiveBorder' ,          TObject(clInactiveBorder)); 
    AddObject('clAppWorkSpace' ,            TObject(clAppWorkSpace)); 
    AddObject('clHighlight' ,               TObject(clHighlight)); 
    AddObject('clHighlightText' ,           TObject(clHighlightText)); 
    AddObject('clBtnFace' ,                 TObject(clBtnFace)); 
    AddObject('clBtnShadow' ,               TObject(clBtnShadow)); 
    AddObject('clGrayText' ,                TObject(clGrayText)); 
    AddObject('clBtnText' ,                 TObject(clBtnText)); 
    AddObject('clInactiveCaptionText' ,     TObject(clInactiveCaptionText)); 
    AddObject('clBtnHighlight' ,            TObject(clBtnHighlight)); 
    AddObject('cl3DDkShadow' ,              TObject(cl3DDkShadow)); 
    AddObject('cl3DLight' ,                 TObject(cl3DLight)); 
    AddObject('clInfoText' ,                TObject(clInfoText)); 
    AddObject('clInfoBk' ,                  TObject(clInfoBk)); 
    AddObject('clHotLight' ,                TObject(clHotLight)); 
    AddObject('clGradientActiveCaption' ,   TObject(clGradientActiveCaption)); 
    AddObject('clGradientInactiveCaption' , TObject(clGradientInactiveCaption)); 
    AddObject('clMenuHighlight' ,           TObject(clMenuHighlight)); 
    AddObject('clMenuBar' ,                 TObject(clMenuBar)); 
  end ;end ;// =============================================================================//   ListBox1のOnClickイベント処理// =============================================================================procedure  TForm1.ListBox1Click(Sender: TObject);var LIndex : Integer; 
  LColor : TColor; 
begin LIndex := ListBox1.ItemIndex; 
  if  LIndex < 0  then  exit;LColor := Integer(ListBox1.Items.Objects[LIndex]); 
  Panel1.Color := LColor; 
end ;end . 
        
          
            
              08_ 16 色 ( 4 ビット色 ) のビットマップのピクセル操作の例 
           
        
        
          
            
              
                  本ページのサンプルでは 256 色のビットマップを扱っていますが,同様のコードで 16 色 (4 ビット) のビットマップ画像も処理できます.ただし,ページの最初で説明しているように,4 ビットのビットマップでは,1 バイトに 2 ピクセル (画素) 分のデータが格納されていることに注意します.
              
                
                
                  4 ビットのビットマップのデータは 1 バイトに 2 ピクセル分格納されていますから,別の 4 ビットのビットマップに転送する時はピクセル数の半分のバイト数を転送します.そのようにしたのが以下のコードです.
 
           
        
        
          
            
              図24 
                  左の元のビットマップは 128 x 128 の 16 色 
                  
           
        
        
          
            
              リスト12  
           
        
copy code 
// =============================================================================//   4ビット(16色)ビットマップの転送例// =============================================================================procedure  TForm1.Button1Click(Sender: TObject);var LSrcBitmap    : TBitmap; 
  LDstBitmap    : TBitmap; 
  LSrcScanArray : PByteArray; 
  LDstScanArray : PByteArray; 
  LPosX         : Integer; 
  LPosY         : Integer; 
begin Image1.Transparent := True; 
  Image2.Transparent := True; 
  Image1.Picture.Assign(nil ); 
  Image2.Picture.Assign(nil ); 
  LSrcBitmap := TBitmap.Create; 
  LDstBitmap := TBitmap.Create; 
  try // 16色のビットマップ画像を読み込んでTImageに表示LSrcBitmap.LoadFromFile('503.bmp' ); 
    Image1.Picture.Assign(LSrcBitmap); 
    //16 色のビットマップを生成LDstBitmap.PixelFormat := pf4bit; 
    LDstBitmap.Width       := LSrcBitmap.Width; 
    LDstBitmap.Height      := LSrcBitmap.Height; 
    // 転送先のビットマップのパレットを,転送元のパレットと同じにするLDstBitmap.Palette := LSrcBitmap.Palette; 
    // ピクセル操作でコピーfor  LPosY := 0  to  LSrcBitmap.Height - 1  do  begin LSrcScanArray := LSrcBitmap.ScanLine[LPosY]; 
      LDstScanArray := LDstBitmap.ScanLine[LPosY]; 
      for  LPosX := 0  to  LSrcBitmap.Width div  2  - 1  do  begin LDstScanArray[LPosX] := LSrcScanArray[LPosX]; 
      end ;end ;Image2.Picture.Assign(LDstBitmap); 
  finally FreeAndNil(LSrcBitmap); 
    FreeAndNil(LDstBitmap); 
  end ;end ;