2013-04-25 89 views
1

我有一個TColor的二維數組。我也有一個TCanvas。如何在畫布上繪製此顏色貼圖的速度比使用週期更快?Delphi如何快速繪製TCanvas上的TColor二維數組?

例如:

type 
    T2DAr = array of array of TColor; 

var 
    ar: T2DAr; 
    Form1: TForm; // mainform 

function main; 
var x, y: integer; 
begin 
{filling array with colors as a 10x10} 

for x := 0 to length(ar)-1 do 
for y := 0 to length(ar[x])-1 do 
Form1.Canvas.Pixels[x, y] := ar[x, y]; 
end; 

這樣的工作過於緩慢。我需要一個更快的算法。

+3

這已經被回答了很多次。答案是:使用'scanline's。 – 2013-04-25 14:41:11

+0

將TColor的二維數組想象爲一個光柵圖像。因此,把你的顏色矩陣放入位圖,然後將其粘貼到TCanvas上。 @Andreas Rejbrand,TCanvas足夠抽象,沒有掃描線。 – OnTheFly 2013-04-25 14:45:56

+0

我看到了標題,我馬上進來說'掃描線',但看到它已被提及 – 2013-04-25 14:46:53

回答

4

這已經回答了很多次。答案是:使用scanline s代替非常慢的Pixels屬性。例如:

function CreateBitmapReallyFast: TBitmap; 
const 
    WHITE: TRGBTriple = (rgbtBlue: 255; rgbtGreen: 255; rgbtRed: 255); 
    BLACK: TRGBTriple = (rgbtBlue: 0; rgbtGreen: 0; rgbtRed: 0); 
var 
    y: Integer; 
    scanline: PRGBTriple; 
    x: Integer; 
begin 
    result := TBitmap.Create; 
    result.SetSize(1920, 1080); 
    result.PixelFormat := pf24bit; 
    for y := 0 to result.Height - 1 do 
    begin 
    scanline := result.ScanLine[y]; 
    for x := 0 to result.Width - 1 do 
    begin 
     if odd(x) then 
     scanline^ := WHITE 
     else 
     scanline^ := BLACK; 
     inc(scanline); 
    end; 
    end; 
end; 

更酷:

with scanline^ do 
begin 
    rgbtBlue := Random(255); 
    rgbtGreen := Random(255); 
    rgbtRed := Random(255); 
end; 

要嘗試:

procedure TForm1.FormPaint(Sender: TObject); 
var 
    bm: TBitmap; 
begin 
    bm := CreateBitmapReallyFast; 
    try 
    Canvas.Draw(0, 0, bm); 
    finally 
    bm.Free; 
    end; 
end; 

當然,如果你有TRGBTripleTRGBQuad一(包裝)陣列,像素格式的位圖是一樣的,你可以簡單地將Move這個數組從內存中的數據傳給位圖的掃描線。

+0

不,'RGBTRIPLE'是** BGR **,'RGBQUAD'爲** BGRX **,而'TColor'爲** RGBX **(其中X表示附加的僞信道)。 – OnTheFly 2013-04-25 15:20:40

+0

@ user539484:是的,但這是它應該的方式,IIRC。 – 2013-04-25 15:22:17

+0

當然,但通道交換操作與天真分配一樣昂貴。如果將自定義像素格式與TIFF或BITMAPV5一起使用,可能會有一些改進,其中通道交換作業委託給其他軟件甚至硬件。 – OnTheFly 2013-04-25 15:29:00