2013-10-13 34 views
2

我想使用TCanvas的FloodFill功能。 我有一個圖片,它的圖片是一個PNG。 當我打電話如何將FloodFill用於在TImage中加載的Png圖形?

Image1.Canvas.FloodFill(20,20,clRed,fsBorder); 

引發的錯誤,並表示

我寫了一段代碼,這樣解決我的問題:「如果它包含了一個位圖只能修改的圖像」。

procedure myChangeColor(p:TPngImage;colorSrc,ColorDest:TColor); 
var i:Integer; 
    j: Integer; 
begin 
    for i := 0 to p.Width - 1 do 
    for j := 0 to p.Height - 1 do 
     if(p.Canvas.Pixels[i,j]=ColorSrc)then 
     p.Canvas.Pixels[i,j]:=ColorDest; 
end; 

它工作正常!但問題是,它需要很多時間來執行此操作:(

我的PNG圖像是1.3 MB(高分辨率。14288x7200像素=> 1.02億像素),它需要大約2分鐘來改變顏色。一定有辦法的。因爲Photoshop中與它的油漆桶做了大約2秒。

如何使用floodfill在德爾福PNG圖像?

+1

['Scanline'(http://docwiki.embarcadero.com/Libraries/XE2/en/Vcl。 Imaging.pngimage.TPngImage.Scanline)將是比「像素」更好的替代方案。 –

+0

@LU RD:非常感謝!如果U發佈了一段代碼,我應該將其標記爲答案。但是U沒有,我可以從那條掃描線得到我想要的。說實話scanline比FloodFill在我的情況下更好。因爲我正在研究一個應該在監視過程中每分鐘更改一次國家顏色的地圖組件。我們有許多國家的邊界​​比較複雜,如果我想使用FloodFill,這將是一項艱鉅的工作,爲每個國家的png文件節省一些點以用於FloodFill功能。這條掃描線非常適合我的工作:D – Loghman

+0

好吧,但是由於使用'ScanLine'並沒有回答如何將FloodFill用於PNG圖像的問題,我只是給出了一個很好的選擇。如果您在實施ScanLine零件時遇到任何問題,這可能是一個新問題。快樂編碼:-) –

回答

3

轉換PNG第一成位圖,然後你就可以用帆布對於這樣的繪圖:

procedure TForm15.Image1Click(Sender: TObject); 
var 
    b: TBitmap; 
    c: TCanvas; 
begin 

    // convert PNG->BITMAP 
    b := TBitmap.Create; 
    b.Assign(Image1.Picture.Graphic); 
    Image1.Picture.bitmap := b; 
    FreeAndNil(b); 

    // draw 
    c := image1.Canvas; 
    c.Brush.Color := clBlue; 
    c.Brush.Style := bsDiagCross; 
    c.FloodFill(100,100,clBlack, fsBorder); 
end; 

UPDATE:If你需要保持它在PNG:

procedure TForm15.Image1Click(Sender: TObject); 
var 
    b: TBitmap; 
    c: TCanvas; 
    png: TPngImage; 
begin 
    b := TBitmap.Create; 
    b.Assign(Image1.Picture.Graphic); 

    c := b.Canvas; 
    c.Brush.Color := clBlue; 
    c.Brush.Style := bsDiagCross; 
    c.FloodFill(100,100,clBlack, fsBorder); 

    Image1.Picture.Graphic.Assign(b); 
    b.Free; 
end; 

UPDATE2同樣無需轉換:

procedure TForm15.Image1Click(Sender: TObject); 
var png: TPngImage; 
begin 
    png := (Image1.Picture.Graphic as TPngImage); 
    png.Canvas.Brush.Color := clBlue; 
    png.Canvas.Brush.Style := bsDiagCross; 
    png.Canvas.FloodFill(100,100,clBlack, fsBorder); 
    Image1.Refresh; 
end; 
+0

我測試了你的代碼。它適用於bmp。但!當我想再次將bmp轉換爲png時,它不起作用!爲什麼?我不知道。順便說一句,它必須再次成爲PNG,因爲透明度是必要的。 LU RU建議的掃描線在我的情況下效果更好。謝謝。 – Loghman

+0

@Loghman問題是非常具體的,如果你需要別的東西,你應該改變/更新問題或創建新的任務。 –

+0

:謝謝。最後的代碼工作正常。和U是對的。我問的問題的答案是你的回答。 :) – Loghman