(D6パーソナル)
先日画像回転の高速化でScanLineを教えていただき高速化に成功しました。
どうせなら回転時にピクセル毎の色を加工して一度で色の加工処理をして一層の高速化をしたいと思います。現在のソースの要点は下記のようにしていますが pDests[iy][ix] := pSources[my][mx]; のところで色を取得して、例えば(一定以上の明るさであれば星と判定みたいに選別するとして)
if R+G+B>50 then begin
R1:=255; G1:=255; B1:=255; //適当なRGBを指定したい
end;
このR1,G1,B1を回転後のピクセルに塗る、という処理をしたいのですがScanLineは初めてでやりかたがわかりません。よろしくお願いします。
var
Dest: TBitmap;
pSources, pDests: array of PRGBArray;
soWidth, soHeight, deWidth, deHeight: Integer;
(その他は省略)
Begin
(幅、高、中心座標などの計算と設定)
//** 回転後画像の設定
Dest := TBitmap.Create;
deWidth := sowidth;
deHeight := soheight;
try
Dest.PixelFormat := pf24bit;
dest.Width:=sowidth;
dest.Height:=soheight;
with Dest.Canvas do //白く塗る
begin
Brush.Color := clWhite;
FillRect(Rect(0, 0, soWidth, soHeight));
end;
//** ScanLineキャッシュの作成
//== 元画像
SetLength(pSources, soHeight);
for I := 0 to soHeight - 1 do pSources[I] := Source.ScanLine[I];
//== 回転後の画像
SetLength(pDests, deHeight);
for I := 0 to deHeight - 1 do pDests[I] := Dest.ScanLine[I];
//## 画像の回転
for iy := 0 to soHeight - 1 do begin
dy:=iy-cy; //cy=高さ/2
for ix := 0 to soWidth - 1 do begin
dx:=ix-cx; //cx=幅/2
mx := Trunc(CosRad * dx - SinRad * dy + 0.5+cx);
my := Trunc(SinRad * dx + CosRad * dy + 0.5+cy);
if (mx<sowidth) and (mx>0) and (my<soheight) and (my>0) then begin
pDests[iy][ix] := pSources[my][mx];
end;
end; //ix
end; //iy
finally
Source.Free;
end;
これでわかるかな?
TRGB = packed record
Blue : Byte;
Green : Byte;
Red : Byte;
end;
TRGBArray = array[0..0] of TRGB;
PRGBArray = ^TRGBarray;
var
SrcRow : pRGBArray;
for Y:=0 to H-1 do
begin
SrcRow := Bmp.ScanLine[Y];
for X:=0 to W-1 do
begin
R := SrcRow[X].Red;
G := SrcRow[X].Green;
B := SrcRow[X].Blue;
end;
end;
KHE00221様、解決しました。 ありがとうございます。
いただいたサンプルは1行だけのScanLineでしたのでまず1行づつ変色のテストをして成功しました。最終的には画像の回転がありますので違う行のデータを操作
する必要がありますので各行のデータを(技術的にはよくわからない状況ですが)試しに配列にしてみましたらうまくいきました。下記のテスト例はカラーをモノクロにして上下反転してみました。これができれば思ったことが実現できるはずですのでこれから実装したいと思います。いろいろ工夫してこの技を身につけたいと思います。ありがとうございました。
/////
bmp1.PixelFormat := pf24bit;
bmp2.PixelFormat := pf24bit;
setlength(abmprow1 ,h1);
setlength(abmprow2 ,h1);
for jy := 0 to h1-1 do aBMProw1[jy]:=bmp1.ScanLine[jy];
for jy := 0 to h1-1 do aBMProw2[jy]:=bmp2.ScanLine[jy];
for jy := 0 to h1-1 do //縦方向の繰り返し
begin
ky:=h1-jy-1; //上下反転のy座標
for ix := 0 to w1-1 do //横方向の繰り返し
begin
Rb := abmpRow1[jy][iX].R;
Gb := abmpRow1[jy][iX].G;
Bb := abmpRow1[jy][iX].B;
brt:=trunc(rb*0.3+gb*0.59+bb*0.11);
aBMProw2[ky][ix].R := brt;
aBMProw2[ky][ix].G := brt;
aBMProw2[ky][ix].B := brt;
end;
end;
//最後にFORM1へコピー
form1.Canvas.Draw(0,50,bmp2);
bmp1.Free;
bmp2.Free;
ツイート | ![]() |