処理の大まかな流れは以下のようになる.
なお, ここに示したコードはDelphi メーリングリストにて中村拓男さんが 発案されたコードを一部書き直したものである.
パレットの作成
ビデオドライバに任せる方法
NTSC系加重平均法
単純平均法
各方法の比較
以下のCreateGrayScalePalette関数は,指定された階調のモノクロパレットを作成し,
そのハンドルを返す.
function CreateGrayScalePalette( Tone: Byte ): HPALETTE;
var
Palette: ^TLogPalette;
i: Integer;
begin
GetMem( Palette, SizeOf( TLogPalette ) + SizeOf( TPaletteEntry ) * Tone );
Palette^.palNumEntries := Tone + 1;
Palette^.palVersion := $0300;
for i := 0 to Tone - 1 do begin
Palette^.palPalEntry[ i ].peRed := Tone - i;
Palette^.palPalEntry[ i ].peGreen := Tone - i;
Palette^.palPalEntry[ i ].peBlue := Tone - i;
Palette^.palPalEntry[ i ].peFlags := 0;
end;
Result := CreatePalette( Palette^ );
FreeMem( Palette );
end;
tagLOGPALETTE = packed record
palVersion: Word;
palNumEntries: Word;
palPalEntry: array[0..0] of TPaletteEntry;
end;
TLogPalette = tagLOGPALETTE;
TLogPalette構造体の代わりに,Delphiが独自に定義しているTMaxLogPalette構造体を
使えば,配列要素の動的確保をしなくてもよい.
TMaxLogPalette構造体は,以下のようにpalPalEntryがByte型(256個)の要素を持つように宣言されている.
TMaxLogPalette = packed record
palVersion: Word;
palNumEntries: Word;
palPalEntry: array [Byte] of TPaletteEntry;
end;
function CreateGrayScalePalette( Tone: Byte ): HPALETTE;
var
Palette: TMaxLogPalette;
i: Integer;
begin
Palette.palNumEntries := Tone + 1;
Palette.palVersion := $0300;
for i := 0 to Tone - 1 do begin
Palette.palPalEntry[ i ].peRed := Tone - i;
Palette.palPalEntry[ i ].peGreen := Tone - i;
Palette.palPalEntry[ i ].peBlue := Tone - i;
Palette.palPalEntry[ i ].peFlags := 0;
end;
Result := CreatePalette( PLogPalette( @Palette )^ );
end;
おそらくこの方法が最も速いと思われる.
Drawメソッドで一気に描く.
上で説明したCreateGrayScalePalette関数を使っている.
procedure ColorToGrayScale1( ColorBitmap, GrayScaleBitmap: TBitmap );
var
SourceBitmap: TBitmap;
begin
SourceBitmap := TBitmap.Create;
try
SourceBitmap.Assign( ColorBitmap );
SourceBitmap.PixelFormat := pf24bit;
with GrayScaleBitmap do
begin
PixelFormat := pf8Bit;
Width := SourceBitmap.Width;
Height := SourceBitmap.Height;
Palette := CreateGrayScalePalette( 255 );
Canvas.Draw( 0, 0, SourceBitmap );
end;
finally
SourceBitmap.Free;
end;
end;
この方法は階調値Yを以下の式により計算する方法である.
Y = 0.298912*R + 0.586611*G + 0.114478*B
この式の係数は,日本やアメリカで使われているテレビ放送の規格で使われている係数であり, 各色に対する人間の視感的特性から実験的に求められたものである.
この方法でグレースケール変換を行う場合は,
まず,モノクロ画像となるTBitmapオブジェクトに256階調のモノクロパレットを
割り当てておき,
カラー画像の各ピクセルをスキャンしながら,
上記の計算式に従ってモノクロ画像の各ピクセルの階調値を計算する.
コードを以下に示す.
type
TTriple = packed record R, G, B: Byte; end;
PTriple = ^TTriple;
procedure ColorToGrayScale2( ColorBitmap, GrayScaleBitmap: TBitmap );
var
SourceBitmap: TBitmap;
x, y: Integer;
pSource: PTriple;
pDest: PByte;
begin
SourceBitmap := TBitmap.Create;
try
SourceBitmap.Assign( ColorBitmap );
SourceBitmap.PixelFormat := pf24bit;
with GrayScaleBitmap do
begin
PixelFormat := pf8Bit;
Width := SourceBitmap.Width;
Height := SourceBitmap.Height;
Palette := CreateGrayScalePalette( 255 );
end;
for y := 0 to SourceBitmap.Height - 1 do
begin
pSource := SourceBitmap.ScanLine[ y ];
pDest := GrayScaleBitmap.ScanLine[ y ];
for x := 0 to SourceBitmap.Width - 1 do
begin
pDest^ := Round( 255 - pSource.R * 0.298912 -
pSource.G * 0.586611 -
pSource.B * 0.114478 );
Inc( pSource );
Inc( pDest );
end;
end;
finally
SourceBitmap.Free;
end;
end;
この方法は階調値YをR,G,Bの平均値とする方法である. すなわち,
Y = ( R + G + B ) / 3
コードは以下のようになる.
procedure ColorToGrayScale3( ColorBitmap, GrayScaleBitmap: TBitmap);
var
SourceBitmap: TBitmap;
x, y: Integer;
pSource: PTriple;
pDest: PByte;
begin
SourceBitmap := TBitmap.Create;
try
SourceBitmap.Assign( ColorBitmap );
SourceBitmap.PixelFormat := pf24bit;
with GrayScaleBitmap do
begin
PixelFormat := pf8Bit;
Width := SourceBitmap.Width;
Height := SourceBitmap.Height;
Palette := CreateGrayScalePalette( 255 );
end;
for y := 0 to SourceBitmap.Height - 1 do
begin
pSource := SourceBitmap.ScanLine[ y ];
pDest := GrayScaleBitmap.ScanLine[ y ];
for x := 0 to SourceBitmap.Width - 1 do
begin
pDest^ := 255 - ( pSource.R + pSource.G + pSource.B ) div 3;
Inc( pSource );
Inc( pDest );
end;
end;
finally
SourceBitmap.Free;
end;
end;
苦労した割には,どれもあんまり変わらんな〜
![]() |
|
![]() |
|
![]() |
|
![]() |
| SEO | [PR] 花 おまとめローン Windows7 冷え性対策 | 動画 掲示板 レンタルサーバー ライブチャット SEO | |