グレースケール

 カラー画像を、グレースケール画像に変換表示にします。

グレー画像にする方法としては、
 1.NTSC係数を用いて、変換する。
 2.三色の平均値を使用する。
 3.グレーパレットを使用して、グレー表示にする。

の三つが代表的な方法です。

今時、画像を利用した、測定、判定等以外にグレーの画像を用いることはあまりないでしょう。

NTSC係数による場合は、視覚に合わせて、輝度を調整する方法で、アナログ方式で、カラー画像と、モノクロ画像を、同一の電波で送信する方法として考え出された方式です。
カラー画像信号は輝度(y)と色信号(Cb,Cr)からなっている事になり、輝度がモノクロ時の画像となります。
光りの三原色のうち、視感度はグリーンが一番高く、次が赤、一番感度が低いのはブルーなので、視感度に合わせて、係数で補正をしています。
輝度は、グレーに変換する場合の係数として、赤 0.298912 緑 0.586611 青 0.114478 となっています。
実際には、視覚なので、個人差があり、あまり精度よく計算する必要はありません。
NTSC係数による計算は、GDIのカラー変換マトリックスを使用して変換する方法と、変換テーブルを使用して変換する方法があります。
変換テーブルを使用しないと、各ピクセルごとに演算を行う為、整数演算を使用しても、時間を要します。

GDIプラスの Color Matrix の使用
変換マトリックスを使用した場合、浮動小数点演算があるため、変換に若干時間がかかります。

NTSC係数のマトリックス
  ColorMatrix_GrayScale : TColorMatrix = (
  ( 0.298912, 0.298912, 0.298912, 0.0, 0.0),
  ( 0.586611, 0.586611, 0.586611, 0.0, 0.0),
  ( 0.114478, 0.114478, 0.114478, 0.0, 0.0),
  ( 0.0,         0.0,         0.0,         1.0, 0.0),
  ( 0.0,         0.0,         0.0,         0.0, 1.0));

何も変換しない場合のマトリックス
  ColorMatrix_NormalScale : TColorMatrix = (
  ( 1.0, 0.0, 0.0, 0.0, 0.0),
  ( 0.0, 1.0, 0.0, 0.0, 0.0),
  ( 0.0, 0.0, 1.0, 0.0, 0.0),
  ( 0.0, 0.0, 0.0, 1.0, 0.0),
  ( 0.0, 0.0, 0.0, 0.0, 1.0));

値に、1を超えても設定しても良いのですが、計算した結果が 0を下回る場合は0に、255を超える場合は、255に制限されます。

TColorMatrix の値について詳細

カラーマトリックス
R'=m11*R + m21*G + m31*B + m41 * α + dR
G'=m12*R + m22*G + m32*B + m42 * α + dG
B'=m13*R + m23*G + m33*B + m43 * α + dB
α'=m14*R + m24*G + m34*B + m44 * α +

Wndows の場合、4バイト目の"α"の値はフラグとなり、システム用デフォルトとか、透明色とかの指定用フラグとなるので
m14,m24,m34, m41,m42,m43 には"0"を割り付け、m44には、フラグが変わらないように"1"を割り付けます。
5列目は、5×5のマトリックスにする為のDummyです。
dR,dB,dG,dα の値は、0~1の値が0~255の値に相当します。-1を与えると、その色が0に設定されます。
各色の計算結果は、255を超える場合は255に、0以下は0に設定されます。

次のマトリックスは
  ColorMatrix_GrayScale : TColorMatrix = (
  (-0.298912,-0.298912,-0.298912, 0.0, 0.0),
  (-0.586611,-0.586611,-0.586611, 0.0, 0.0),
  (-0.114478,-0.114478,-0.114478, 0.0, 0.0),
  ( 0.0,          0.0,          0.0,         1.0, 0.0),
  ( 1.0,          1.0,          1.0,         0.0, 1.0));

R'=-0.298912*R -0.586611*G -0.114478*B +0 * α + 255     =  255 - (0.298912*R + 0.586611*G + 0.114478*B)
G'=-0.298912*R -0.586611*G -0.114478*B +0 * α + 255     =  255 - (0.298912*R + 0.586611*G + 0.114478*B)
B'=-0.298912*R -0.586611*G -0.114478*B +0 * α + 255     =  255 - (0.298912*R + 0.586611*G + 0.114478*B)
α'=0.0*R + 0.0*G +0.0*B + 1.0 * α + 0.0                            = α

の計算となり、グレースケールの反転画像となります。

ガンマ補正値
ガンマ補正値ガンマ補正

V=(D/255)1/r× 255
信号の最大値を255とした場合で、アナログ信号の場合は、アナログアンプによる計算なので、
255の値をとるわけではありません。


NTSCにはガンマ補正もあり、ガンマ補正値2.2は、ブラウン管の発光特性を補正するもので、実際にこの値が採用されているわけではありません。
ブラウン管の特性によって、違う値が採用されています。
現在は、ブラウン管は日本からは全く消滅しています
又、モニター、TVカメラもカラー化が進み、モノクロの画像が使用されているのは、監視カメラと、工業用測定カメラ位でしか存在しません。
テレビの放送も、デジタル化された事により、NTSC方式は、監視用テレビカメラと、そのモニターと録画装置位しかなくなってしまいました。
デジタルカメラで撮影された画像は、RGB それぞれの値の最大値が255になっています。

三色の平均値をとる方法は、簡単なのですが、視覚とは少しずれてしまいます、しかし、測定器として使用する場合は、全く問題はありません。
又、測定用としデーターを使用する場合は、配列データーとしたほうが演算が早くなります。
測定用のカメラからパソコンにデーターを取り込むと、一般的には、メモリーへ配列データーとして取り込まれます。
写真用デジタルカメラの場合は、JPGファイルとする方法が一般的です。

グレーパレットの使用は、三色の平均値をとるのと変わりません。
変換はシステムに任せるので、一番早く変換が出来るものと思われます。
グレーパレットを書き込み先のTBitmapに適用すると、カラー画像のビットマップを、グレースケールのビットマップに画像を書き込む時、システムがパレットを使用して、グレー画像に変換します。
グレースケールのビットマップから、表示用イメージに書き出すと、グレースケールにより逆変換して、画像として表示されます。
この時は、変換元の値が、一つなので、グレースケール変換前のカラー画像にはなりません。単一色として表示されます。

サンプル画像
元画像に対して、NTSC係数を使用すると、三食平均に比べ、グリーンの色の部分が明らかに、明るくなっています。
見た感覚も、カラーの時の画像に近いことがわかります。

グレースケールビット
グレースケールとして、8ビット、4ビット、1ビット(白黒)がありますが、プログラム上で画像を扱う場合、8ビット以外は扱い辛いので、4ビット、1ビット(白黒)のデーターを扱うことは無いでしょう。
一昔前は、パソコンのメモリー容量が小さかったため、メモリーの使用量を出来る限り少なくしていました。
現在は、大容量となり、アクセスも早くなりました。

プログラムとして、グレースケールパレットが使用できるようになっているので、参考としてプログラムを組んでみました。

本サンプルプログラムには、画像の保存はありません、保存処理のある画像処理プログラムもあるので、必要であれば、それを参照して追加してください。
保存処理は、アンシャープマスキング画像の回転のプログラムに組み込んであります。

参考プログラム

unit GrayScaleMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.ExtDlgs, system.Types,
  GDIPAPI, GDIPOBJ;
type
  TForm1 = class(TForm)
    FileOpen: TButton;
    Image1: TImage;
    Image2: TImage;
    OpenPictureDialog1: TOpenPictureDialog;
    GrayScaleBtn: TButton;
    GrayScaleDBtn: TButton;
    GrayScaleABtn: TButton;
    GrayScale24Btn: TButton;
    GrayScale4btn: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FileOpenClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure GrayScaleBtnClick(Sender: TObject);
    procedure GrayScaleDBtnClick(Sender: TObject);
    procedure GrayScaleABtnClick(Sender: TObject);
    procedure GrayScale24BtnClick(Sender: TObject);
    procedure GrayScale4btnClick(Sender: TObject);
    procedure GrayMatBtnClick(Sender: TObject);
  private
    { Private 宣言 }
    procedure TemplateMake;      // Templateデーター作成
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

type
  TPrgbarry = array[0..0] of Trgbtriple;      // 24ビットカラーレコード 32ビット用はTRGBQuadArray
  Prgbarray  = ^TPrgbarry;                    // ポインター
                                              // 配列のポインターが必要なだけなので、長さは1 [0..0]で問題ありません。

// TMaxLogPaletteを使用しても良いのですが、4ビット用グレースケールを宣言してみました
  T16LogPalette = packed record               // 4ビット用グレースケール パレット レコード Delphiにないので此処で宣言
    palVersion: Word;                         // Delphi では record の可変長宣言できません
    palNumEntries: Word;
    palPalEntry: array [0..15] of TPaletteEntry; // TPaletteEntryは32 ビットカラー
  end;


implementation

{$R *.dfm}
const
  OpenFileFilter =
    '画像ファイル|*.png;*.jpg;*.gif;*.bmp;*.tif;*.ico;*.wdp'+
    '|*.png|*.png' +
    '|*.jpg|*.jpg' +
    '|*.gif|*.gif' +
    '|*.bmp|*.bmp' +
    '|*.tif|*.tif' +
    '|*.ico|*.ico' +
    '|*.wdp|*.wdp';

  SaveFileFilter =
    '画像ファイル|*.png;*.jpg;*.gif;*.bmp;*.tif;*.wdp' +
    '|*.png|*.png' +
    '|*.jpg|*.jpg' +
    '|*.gif|*.gif' +
    '|*.bmp|*.bmp' +
    '|*.tif|*.tif' +
    '|*.wdp|*.wdp';

  ImageHW   = 384;                            // 表示枠サイズ


  RK    = 0.298912;                           // グレースケール輝度係数 赤
  GK    = 0.586611;                           // グレースケール輝度係数 緑
  BK    = 0.114478;                           // グレースケール輝度係数 青
  BISU  = 1024;                               // 整数化倍数
  RSISF = 10;                                 // ビットシフト数


  ColorMatrix_GrayScale : TColorMatrix = (          // GDI カラーコントロールマトリックス
  ( 0.298912, 0.298912, 0.298912, 0.0, 0.0),
  ( 0.586611, 0.586611, 0.586611, 0.0, 0.0),
  ( 0.114478, 0.114478, 0.114478, 0.0, 0.0),
  ( 0.0,      0.0,      0.0,      1.0, 0.0),
  ( 0.0,      0.0,      0.0,      0.0, 1.0));

var
  InBitmap        : TBitmap;                  // ビットマップ
  OutBitmap       : TBitmap;
  OutBitmap24     : TBitmap;
  OutBitmap4      : TBitmap;
  GHeight, GWidth : integer;                  // ソース画像サイズ
  Vrect           : Trect;                    // 表示枠
  IHeight, IWidth : Integer;                  // 表示サイズ
  RTemp           : array[0..255] of Cardinal;  // テンプレート用配列 赤
  GTemp           : array[0..255] of Cardinal;  // テンプレート用配列  緑
  BTemp           : array[0..255] of Cardinal;  // テンプレート用配列  青

// Tone に階調をセット 使用できるのは 256, 16, 2  です。
function CreateGrayScalePaletteS(Tone: WORD): HPALETTE; // Tone に階調をセット
var
  Palette : ^TLogPalette;                               // TLogPalette のポインター
  i       : Integer;
  BD      : BYTE;
begin
   GetMem(Palette, SizeOf(TLogPalette) + SizeOf(TPaletteEntry) * Tone);   // TLogPaletteは固定長の配列なので必要なメモリ確保
   Palette^.palNumEntries := Tone;                                        // 階調セット
   Palette^.palVersion := $0300;                                          // バージョンセット
   BD := 255 div (Tone - 1);                                              // 階調差計算
   for i := 0 to Tone - 1 do begin                                        // 階調データーセット
      Palette^.palPalEntry[i].peRed   := BD * i;
      Palette^.palPalEntry[i].peGreen := BD * i;
      Palette^.palPalEntry[i].peBlue  := BD * i;
      Palette^.palPalEntry[i].peFlags := 0;                               // フラグは使用しない
   end;
   Result := CreatePalette(Palette^);
   FreeMem(Palette);
end;

// 16諧調
function Create16ScalePalette: HPALETTE;            // グレー4ビットパレットに設定
const
  Tone = 16;                                        // 16階調
var
  Palette: T16LogPalette;
  i: Integer;
begin
  Palette.palNumEntries := Tone;                    // 16階調セット
  Palette.palVersion := $0300;                      // パレットバージョン
  for i := 0 to Tone - 1 do begin                   // パレットデーターの設定
    Palette.palPalEntry[ i ].peRed   := 17 * i;       // 17 = 255 / 15      15 = Tone - 1 
    Palette.palPalEntry[ i ].peGreen := 17 * i;
    Palette.palPalEntry[ i ].peBlue  := 17 * i;
    Palette.palPalEntry[ i ].peFlags := 0;          // フラグは使用しない
  end;
  Result := CreatePalette(PLogPalette(@Palette)^);
end;

// 256諧調
function CreateGrayScalePalette: HPALETTE;          // グレー8ビットパレットに設定
const
  Tone = 256;                                       // 256階調
var
  Palette: TMaxLogPalette;
  i: Integer;
begin
  Palette.palNumEntries := Tone;                    // 256階調セット
  Palette.palVersion := $0300;                      // パレットバージョン
  for i := 0 to Tone - 1 do begin                   // パレットデーターの設定
    Palette.palPalEntry[ i ].peRed   := i;
    Palette.palPalEntry[ i ].peGreen := i;
    Palette.palPalEntry[ i ].peBlue  := i;
    Palette.palPalEntry[ i ].peFlags := 0;
  end;
  Result := CreatePalette(PLogPalette(@Palette)^);
end;

// NTSC 係数を1024倍してテンプレートデーター作成
procedure TForm1.TemplateMake;      // Templateデーター作成
var
  II : Integer;
begin
  for II := 0 to 255 do begin
    RTemp[II] := round(RK * BISU * II);                       // 赤テンプレート
    GTemp[II] := round(GK * BISU * II);                       // 緑テンプレート
    BTemp[II] := round(BK * BISU * II);                       // 青テンプレート
  end;
end;

// ファイルのオープン WIC がファイルの種類が多いので使用
procedure TForm1.FileOpenClick(Sender: TObject);
var
  WIC         : TWICImage;
  InFilename  : String;
begin
  GrayScaleBtn.Enabled    := False;
  GrayScaleDBtn.Enabled   := False;
  GrayScaleABtn.Enabled   := False;
  GrayScale24Btn.Enabled  := False;
  GrayScale4Btn.Enabled := False;
  GrayMatBtn.Enabled    := False;
  VRect := Rect(0, 0, Image1.Width, Image1.Height);
  Image1.Canvas.Brush.Style := bsSolid;
  Image1.Canvas.Brush.Color := clBtnface;
  Image1.Canvas.FillRect(VRect);                              // Canvas 画像消去
  Image2.Canvas.Brush.Style := bsSolid;
  Image2.Canvas.Brush.Color := clBtnface;
  Image2.Canvas.FillRect(VRect);                              // Canvas 画像消去
  OpenPictureDialog1.Filter := OpenFileFilter;                // ファイルオープンフィルターの設定
  if OpenPictureDialog1.Execute then                          // ファイルが指定されたら
    begin
      WIC := TWICImage.Create;                                // TWICImageの生成
      try
        InFilename := OpenPictureDialog1.FileName;            // ファイル名の取得
        WIC.LoadFromFile(InFilename);                         // 画像の読み込み
        GHeight := WIC.Height;                                // 画像高さ取得
        GWidth  := WIC.Width;                                 // 画像幅
        IWidth  := ImageHW;                                   // 出力先イメージ1の幅
        IHeight := ImageHW;                                   // 出力先イメージ1の高さ
        if GHeight <= GWidth then                             // 縦横比により出力サイズ設定
          IHeight := Round(IWidth * GHeight / GWidth)
        else
          IWidth := Round(IHeight * GWidth / GHeight);
        Image1.Width := IWidth;
        Image1.Height:= IHeight;
        Image1.Picture.Bitmap.SetSize(IWidth, IHeight);       // 表示用ビットマップサイズの設定
        Image2.Width := IWidth;
        Image2.Height:= IHeight;
        Image2.Picture.Bitmap.SetSize(IWidth, IHeight);       // 表示用ビットマップサイズの設定
        VRect := Rect(0, 0, IWidth, IHeight);                 // 出力枠設定
        Image1.Canvas.StretchDraw(VRect, WIC);                // 出力枠に変倍出力
        InBitmap.Width    := GWidth;
        InBitmap.Height   := GHeight;
        InBitmap.Canvas.Draw(0, 0, WIC);                      // DrawでInBitmapに入力画像設定フォーマット24ビットに変換されます
        OutBitmap.Width   := GWidth;
        OutBitmap.Height  := GHeight;
        OutBitmap24.Width := GWidth;
        OutBitmap24.Height:= GHeight;
        OutBitmap4.Width  := GWidth;
        OutBitmap4.Height := GHeight;
      finally
        WIC.Free;                                             // TWICImage 解放
      end;
    end
    else Exit;
  GrayScaleBtn.Enabled    := True;
  GrayScaleDBtn.Enabled   := True;
  GrayScaleABtn.Enabled   := True;
  GrayScale24Btn.Enabled  := True;
  GrayScale4Btn.Enabled   := True;
  GrayMatBtn.Enabled      := True; 
end;

// マトリックスを使用してグレー画像の生成
procedure TForm1.GrayMatBtnClick(Sender: TObject);
var
  Gpgraph : TGPGraphics;
  GPImage : TGPImage;
  GPImageAttr : TGPImageAttributes;
  Astream : TMemoryStream;
begin
  // GPImage := TGPImage.Create(InFilename); // TGPImageにファイル名関連付け
  // ファイルから読み込む代わりにメモリーへ出力しメモリーから読み込みます
  // メモリーストリームを作成し inbitmap を出力
  Astream := TMemoryStream.Create;
  InBitmap.SaveToStream(Astream);

  // メモリーストリームから,TGPBitmapのオブジェクトに読み込み指定
  GPImage := TGPBitmap.Create(TStreamAdapter.Create(AStream, soReference));

  // GD+にTBitmapの描画ハンドル設定
  Gpgraph := TGPGraphics.Create(OutBitmap24.Canvas.Handle);

  // TGPImageAttributesのオブジェクトを生成
  GPImageAttr := TGPImageAttributes.Create;

  // 使用するマトリックスをアトリビュートに設定
  GPImageAttr.SetColorMatrix(ColorMatrix_GrayScale);

  // TCanvasのStretchDrawに相当する
  // GpgraphのHandleがOutBitmap24.Canvasに指定されているのでOutBitmap24.Canvasに描画されます
  Gpgraph.DrawImage(                                      // Gpgraph (OutBitmap24) に描画
              GPImage,                                    // 元画像
              MakeRect(0, 0, GWidth, GHeight),            // 出力位置 サイズ 
              0, 0, GPImage.GetWidth, GPImage.GetHeight,  // 入力位置 サイズ
              UnitPixel,                                  // ピクセル
              GPImageAttr);                               // アトリビュート

  Image2.Canvas.StretchDraw(Vrect, OutBitmap24);          // Image1に Dbitmap変倍表示

  //Createしたオブジェクトは解放処理します。
  GPImageAttr.Free;
  GPImage.Free;
  Gpgraph.Free;
  Astream.Free;
end;

// パレットを使用せずに、24ビットカラーモード R,G,B  に同じ値を書き込みます
procedure TForm1.GrayScale24BtnClick(Sender: TObject);        // パレットを使用せずRGB同じ値セット
var
  II, JJ        : Integer;
  InpPrgbarray  : Prgbarray;
  OutParray     : Prgbarray;
  OutInt        : DWORD;
  OutByte       : BYTE;
begin
  for II := 0 to GHeight - 1 do begin
    InpPrgbarray  := InBitmap.ScanLine[II];                   // ラインポインタ設定
    OutParray     := OutBitmap24.ScanLine[II];
    for JJ := 0 to GWidth - 1 do begin                        // 三色加算
      OutInt :=   RTemp[InpPrgbarray[JJ].rgbtRed]             // 赤テンプレート
                + GTemp[InpPrgbarray[JJ].rgbtGreen]           // 緑テンプレート
                + BTemp[InpPrgbarray[JJ].rgbtBlue];           // 青テンプレート
      OutByte := OutInt shr RSISF;                            // 10ビット右シフト OutInt div 10
      OutParray[JJ].rgbtBlue  := OutByte;                     // 三色同じ値をセット
      OutParray[JJ].rgbtGreen := OutByte;
      OutParray[JJ].rgbtRed   := OutByte;
    end;
  end;
  Image2.Canvas.StretchDraw(VRect, OutBitmap24);              // 出力枠に変倍出力
end;

// 16階調グレーパレットを使用して表示
procedure TForm1.GrayScale4btnClick(Sender: TObject);         // 4ビット 16階調表示
var                                                           // NTSC係数使用
  II, JJ        : Integer;
  InpPrgbarray  : Prgbarray;
  OutParray     : Prgbarray;
  OutInt        : DWORD;
  OutByte       : BYTE;
begin
  for II := 0 to GHeight - 1 do begin
    InpPrgbarray  := InBitmap.ScanLine[II];                   // ラインポインタ設定
    OutParray     := OutBitmap24.ScanLine[II];
    for JJ := 0 to GWidth - 1 do begin                        // 三色加算
      OutInt :=   RTemp[InpPrgbarray[JJ].rgbtRed]             // 赤テンプレート
                + GTemp[InpPrgbarray[JJ].rgbtGreen]           // 緑テンプレート
                + BTemp[InpPrgbarray[JJ].rgbtBlue];           // 青テンプレート
      OutByte := OutInt shr RSISF;                            // 10ビット右シフト OutInt div 1024
      OutParray[JJ].rgbtBlue  := OutByte;                     // 三色同じ値をセット
      OutParray[JJ].rgbtGreen := OutByte;
      OutParray[JJ].rgbtRed   := OutByte;
    end;
  end;
  OutBitmap4.Canvas.Draw(0, 0, OutBitmap24);                  // 16階調パレットに描画
  Image2.Canvas.StretchDraw(VRect, OutBitmap4);               // 出力枠に変倍出力
end;

// R,G,Bの平均値を使用して、表示 表示は256階調グレーパレット使用
procedure TForm1.GrayScaleABtnClick(Sender: TObject);         // 平均値計算出力
var
  II, JJ        : Integer;
  InpPrgbarray  : Prgbarray;
  OutParray     : Pbytearray;
  OutInt        : WORD;
begin
  for II := 0 to GHeight - 1 do begin
    InpPrgbarray  := InBitmap.ScanLine[II];                   // ラインポインタ設定
    OutParray     := OutBitmap.ScanLine[II];
    for JJ := 0 to GWidth - 1 do begin                        // 三色加算
      OutInt :=   InpPrgbarray[JJ].rgbtRed                    // 赤
                + InpPrgbarray[JJ].rgbtGreen                  // 緑
                + InpPrgbarray[JJ].rgbtBlue;                  // 青
      OutParray[JJ] := OutInt div 3;                          // 平均値 OutInt div 3
    end;
  end;
  Image2.Canvas.StretchDraw(VRect, OutBitmap);                // 出力枠に変倍出力
end;

// NTSC係数を使用して輝度計算 グレースケールパレット使用して表示
procedure TForm1.GrayScaleBtnClick(Sender: TObject);          // グレースケール変換
var                                                           // NTSC係数使用
  II, JJ        : Integer;
  InpPrgbarray  : Prgbarray;
  OutParray     : Pbytearray;
  OutInt        : DWORD;
begin
  for II := 0 to GHeight - 1 do begin
    InpPrgbarray  := InBitmap.ScanLine[II];                   // ラインポインタ設定
    OutParray     := OutBitmap.ScanLine[II];
    for JJ := 0 to GWidth - 1 do begin
      OutInt :=   RTemp[InpPrgbarray[JJ].rgbtRed]             // 赤テンプレート
                + GTemp[InpPrgbarray[JJ].rgbtGreen]           // 緑テンプレート
                + BTemp[InpPrgbarray[JJ].rgbtBlue];           // 青テンプレート
      OutParray[JJ] := OutInt shr RSISF;                      // 10ビット右シフト OutInt div 1024
    end;
  end;
  Image2.Canvas.StretchDraw(VRect, OutBitmap);                // 出力枠に変倍出力
end;

// グレースケールパレットを使用して、直接変換表示
procedure TForm1.GrayScaleDBtnClick(Sender: TObject);         // 直接出力 変換は システム任せ
begin
  OutBitmap.Canvas.Draw(0, 0, InBitmap);                      // OutBitmapに描画、グレー変換はパレット任せ
  Image2.Canvas.StretchDraw(VRect, OutBitmap);                // 出力枠に変倍出力
end;

// 初期設定
procedure TForm1.FormCreate(Sender: TObject);
begin
  GrayScaleBtn.Enabled  := False;
  GrayScaleDBtn.Enabled := False;
  GrayScaleABtn.Enabled := False;
  GrayScale24Btn.Enabled := False;
  GrayScale4Btn.Enabled := False;
  Image1.Width  := ImageHW;
  Image1.Height := ImageHW;
  Image2.Width  := ImageHW;
  Image2.Height := ImageHW;
  InBitmap      := TBitmap.Create;                            // 入力画像用
  OutBitmap     := TBitmap.Create;                            // 8ビット出力用
  OutBitmap24   := TBitmap.Create;                            // 24ビット出力用
  OutBitmap4    := TBitmap.Create;                            // 4ビット出力用
  InBitmap.PixelFormat    := pf24bit;                         // 24ビットカラーに設定
  OutBitmap24.PixelFormat := pf24bit;                         // 24ビットカラーに設定
  OutBitmap.PixelFormat   := pf8bit;                          // 8ビットに設定
  OutBitmap.Palette := CreateGrayScalePalette;                // グレイ256階調に設定
  OutBitmap4.PixelFormat  := pf4bit;                          // 4ビットに設定
//  OutBitmap4.Palette := Create16ScalePalette;
  OutBitmap4.Palette := CreateGrayScalePaletteS(16);          // グレー16階調にパレット設定
  TemplateMake;                                               // Templateデーター作成
end;

// ビットマップの解放
procedure TForm1.FormDestroy(Sender: TObject);
begin
  InBitmap.Free;
  OutBitmap.Free;
  OutBitmap24.Free;
  OutBitmap4.Free;
end;

end.

    download GrayScale.zip

画像処理一覧へ戻る

      最初に戻る