全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1505
推到 Plurk!
推到 Facebook!

請問畫圖工具中的填充工具的演算法如何實現?

尚未結案
ychx
一般會員


發表:40
回覆:14
積分:10
註冊:2003-08-03

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-06-08 11:00:25 IP:218.0.xxx.xxx 未訂閱
請問哪位大俠有畫圖工具中的填充工具的演算法,請賜小弟一法,不甚感激!
aquarius
資深會員


發表:3
回覆:347
積分:330
註冊:2003-05-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-06-17 17:24:09 IP:211.23.xxx.xxx 未訂閱
可以參考一下別人寫的 http://www.delphibox.com/article.asp?articleid=1117 其實這些填充演算法, 在電腦圖學的書上也都會提到, 多看點書應該灳不難做出來啦!! 不過, 更快的是直接呼叫 FloodFill , 呵呵. ...Aquarius
------
水瓶男的blog: http://791909.blogspot.com
sigmaccc
一般會員


發表:32
回覆:40
積分:14
註冊:2003-11-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-10-13 10:20:08 IP:220.130.xxx.xxx 未訂閱
引言: 可以參考一下別人寫的 http://www.delphibox.com/article.asp?articleid=1117 其實這些填充演算法, 在電腦圖學的書上也都會提到, 多看點書應該灳不難做出來啦!! 不過, 更快的是直接呼叫 FloodFill , 呵呵. ...Aquarius
那個連結已經不見了,可否再請大大同次提供資料? 因為要用800x600 256色模式寫DOS程式,所以floodfill必需自行撰寫。 發表人 - sigmaccc 於 2004/10/13 10:38:37
japhenchen
高階會員


發表:51
回覆:444
積分:184
註冊:2003-07-23

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-10-15 09:42:42 IP:219.134.xxx.xxx 未訂閱
給你一個簡單的想法~~用遞迴的方法~~    
function FillColor(aCanvas:TCanvas;ax,ay,PickColor,acolor:Integer):boolean;
//                 aCanvas你想要填充的畫布
//                 ax,ay 要偵測的點
//                 pickcolor 要被填充的顏色 
//                 acolor 要填充的顏色
begin
   if aCanvas.Pixels[ax,ay]=PickColor then begin
      aCanvas.Pixels[ax,ay]:=aColor;
      // 想法很簡單,如果指定的點跟原來一開始被指定的點相同色,則換色
      FillColor(aCanvas,ax,ay-1,PickColor,aColor);
      FillColor(aCanvas,ax-1,ay,PickColor,aColor);
      FillColor(aCanvas,ax 1,ay,PickColor,aColor);
      FillColor(aCanvas,ax,ay 1,PickColor,aColor);
      //上下左右四點偵測法,遞回這個函數進行重覆的工作
      //如果臨近的四個點跟一開始設定的點顏色不同,這里根本不會進行,也就是遇邊界了
   end;
end;    procedure TForm.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   fillcolor(Image1.Picture.Bitmap.Canvas,
             x,y,
             Image1.Picture.Bitmap.Canvas.Pixels[x,y],
             clBlack);
end;
任何一種多邊形、圓形,只要是封閉的區塊都可以進行,不然就floodfill洪水潰堤了! 這個方法有個大缺點,由於使用遞迴,需要大量的堆疊空間才能跑,不然會出現stack overflow的錯誤,二種改進的方法,一是加大堆疊空間,二就是自己寫堆疊器來記錄(那就不能用遞迴囉) 第二種改進的方法可以請各位大大一塊來發揮唄~ 藏私の禁止
japhenchen
高階會員


發表:51
回覆:444
積分:184
註冊:2003-07-23

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-10-15 13:02:34 IP:219.134.xxx.xxx 未訂閱
不用遞迴的方法,變相的使用堆疊來做記錄,改用較快的scanline改進填充速度    
procedure FillColor(aBmp:TBitmap;ax,ay,PickColor,acolor:Integer);
type
   StackField=Record
      xl , xr ,y : integer;
   end;
type
  PArr = ^TRGBTripleArray;
  TRGBTripleArray = array [Byte] of TRGBTriple;
var Stack : array of StackField;
    NoEdge: boolean ;
    px,py,nx,ny,pyd : integer;
    xBmp : TBitmap;
    pcolor : TColor ;
    p: PArr;       procedure ResetStack;
   begin
      SetLength(Stack,1);
      Stack[0].y:=0;
   end;
   function isStackEmpty:boolean;
   begin
      Result:=(Stack[0].y=0);
   end;
   procedure Push(xl,xr,yd:integer);
   begin
      inc(Stack[0].y);
      if Stack[0].y>length(Stack)-1 then
         Setlength(Stack,length(Stack) 1);
      Stack[Stack[0].y].xl:=xl;
      Stack[Stack[0].y].xr:=xr;
      Stack[Stack[0].y].y:=yd;
   end;
   procedure Pop(var xl,xr,yd:integer);
   begin
       if Stack[0].y>0 then begin
          xl:=Stack[Stack[0].y].xl;
          xr:=Stack[Stack[0].y].xr;
          yd:=Stack[Stack[0].y].y;
          dec(Stack[0].y);
          setlength(Stack,length(Stack)-1);
       end;
   end;
begin
   xBmp:=TBitmap.Create;
   xBmp.PixelFormat:=pf24bit;
   xBmp.Width:=aBmp.Width;
   xBmp.Height:=aBmp.Height;
   xbmp.Canvas.Draw(0,0,abmp);       ResetStack;       P:=xBmp.ScanLine[ay];
   p[ax*3 1].rgbtRed:=0;
   pcolor:= p[ax].rgbtRed or(p[ax].rgbtGreen shl 8)or(p[ax].rgbtBlue shl 16);       px:=ax;
   py:=ay;
   noEdge:=false;
   Push(px,py,0);
   p[px].rgbtRed:=aColor and $000000FF;
   p[px].rgbtGreen:=(aColor and $0000FF00)shr 8;
   p[px].rgbtBlue:=(aColor and $00FF0000)shr 16;       Application.ProcessMessages;
   while (not NoEdge) and (not isStackEmpty) do begin
      noEdge:=true;
      if (px-1)>=0 then begin
         P:=xBmp.ScanLine[py];
         pcolor:= p[px-1].rgbtRed or(p[px-1].rgbtGreen shl 8)or(p[px-1].rgbtBlue shl 16);
         if pColor=PickColor then begin
            p[px-1].rgbtRed:=aColor and $000000FF;
            p[px-1].rgbtGreen:=(aColor and $0000FF00)shr 8;
            p[px-1].rgbtBlue:=(aColor and $00FF0000)shr 16;
            noEdge:=false;
            push(px-1,py,0);
         end;
      end;
      if (py-1)>=0 then begin
         P:=xBmp.ScanLine[py-1];
         pcolor:= p[px].rgbtRed or(p[px].rgbtGreen shl 8)or(p[px].rgbtBlue shl 16);
         if pColor=PickColor then begin
            p[px].rgbtRed:=aColor and $000000FF;
            p[px].rgbtGreen:=(aColor and $0000FF00)shr 8;
            p[px].rgbtBlue:=(aColor and $00FF0000)shr 16;
            noEdge:=false;
            push(px,py-1,0);
         end;
      end;
      if (px 1)    藏私の禁止
        
系統時間:2024-04-26 2:14:47
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!