ScanLineの2次配列化 (Delphi)
Delphiで画像をご存知と思いますが、BitmapのPixelsプロパティを使ってのピクセル色の取得・設定は画像処理などでループ作業をする場合、非常に時間がかかります。
そこで通常はScanLineを使うわけですが、横一ライン分の画素しか持てません。対象ピクセルから数ドット上のピクセルを参照、なんて場合は無駄に面倒なルーチンを組まないといけません。
そこで、ポインタを使って2次配列化するやり方を載せていたサイトがあったのですが、どうも数年経つ間にサイトが消えてしまったようです。
{RGB構造体定義}
type TRGB = record B,G,R:Byte end;
PRGB =^TRGB;
TLine = array[0..0]of TRGB;
PLine =^TLine;
TPLines = array[0..0]of PLine;
PPLines =^TPLines;
{2次配列に変換}
function GetPixelArray(Bitmap:TBitmap):PPLines;
var
i :integer;
h :integer;
begin
Result:=nil;
if Bitmap.Empty then exit;
h := Bitmap.Height;
Result := Allocmem(sizeof(PLine)*h);
for i:=0 to h-1 do
Result^[i] := Bitmap.ScanLine[i];
end;
{メモリ解放}
procedure FreePixelArray(var PixelArray:PPLines);
begin
if PixelArray <> nil then begin
Freemem(PixelArray);
PixelArray := nil;
end;
end;
{使用例:画像のネガポジ反転コピー}
procedure Invert(SrcBitmap,DstBitmap:TBitmap);
var
Src :PPLines;
Dst :PPLines;
i,j :integer;
begin
Src := GetPixelArray(SrcBitmap);
Dst := GetPixelArray(DstBitmap);
for i := 0 to SrcBitmap.Height - 1 do
for j := 0 to SrcBitmap.Width - 1 do
begin
Dst[i,j].R := 255 - Src[i,j].R; //座標は[Y,X]となります
Dst[i,j].G := 255 - Src[i,j].G;
Dst[i,j].B := 255 - Src[i,j].B;
end;
FreePixelArray(Dst); //メモリを解放してください
FreePixelArray(Src);
end;
24Bit同サイズのビットマップ前提です。
参考リンク
最終更新:2006年12月17日 00:10