[轉]C語言圖形編程(三) -繪圖函數②

 四、圖形和圖像函數
(一) 像素函數

    56. putpiel() 畫像素點函數
    57. getpixel()返回像素色函數
(二) 直線和線型函數
    58. line() 畫線函數
    59. lineto() 畫線函數
    60. linerel() 相對畫線函數
    61. setlinestyle() 設置線型函數
    62. getlinesettings() 獲取線型設置函數
    63. setwritemode() 設置畫線模式函數
(三)、多邊形函數
    64. rectangle() 畫矩形函數
    65. bar() 畫條函數
    66. bar3d() 畫條塊函數
    67. drawpoly() 畫多邊形函數
(四)、 圓、弧和曲線函數
    68. getaspectratio()獲取縱橫比函數
    69. circle()畫圓函數
    70. arc() 畫圓弧函數
    71. ellipse()畫橢圓弧函數
    72. fillellipse() 畫橢圓區函數
    73. pieslice() 畫扇區函數
    74. sector() 畫橢圓扇區函數
    75. getarccoords()獲取圓弧座標函數
(五)、 填充函數
    76. setfillstyle() 設置填充圖樣和顏色函數
    77. setfillpattern() 設置用戶圖樣函數
    78. floodfill() 填充閉域函數
    79. fillpoly() 填充多邊形函數
    80. getfillsettings() 獲取填充設置函數
    81. getfillpattern() 獲取用戶圖樣設置函數
(六)、圖像函數
    82. imagesize() 圖像存儲大小函數
    83. getimage() 保存圖像函數
    84. putimage() 輸出圖像函數




四、圖形和圖像函數
   對許多圖形應用程序,直線和曲線是非常有用的。但對有些圖形只能靠操作單個像素才能畫出。當然如果沒有畫像素的功能,就無法操作直線和曲線的函數。而且通過大規模使用像素功能,整個圖形就可以保存、寫、擦除和與屏幕上的原有圖形進行疊加。
(一) 像素函數

56. putpixel() 畫像素點函數
功能: 函數putpixel() 在圖形模式下屏幕上畫一個像素點。
用法: 函數調用方式爲void putpixel(int x,int y,int color);
說明: 參數x,y爲像素點的座標,color是該像素點的顏色,它可以是顏色符號名,也可以是整型色彩值。
       此函數相應的頭文件是graphics.h
返回值: 無
例: 在屏幕上(6,8)處畫一個紅色像素點:
   putpixel(6,8,RED);

57. getpixel()返回像素色函數
功能: 函數getpixel()返回像素點顏色值。
用法: 該函數調用方式爲int getpixel(int x,int y);
說明: 參數x,y爲像素點座標。
       函數的返回值可以不反映實際彩色值,這取決於調色板的設置情況(參見setpalette()函數)。
       這個函數相應的頭文件爲graphics.h
返回值: 返回一個像素點色彩值。
例: 把屏幕上(8,6)點的像素顏色值賦給變量color。
   color=getpixel(8,6);

(二) 直線和線型函數
   有三個畫直線的函數,即line(),lineto(),linerel()。這些直線使用整型座標,並相對於當前圖形視口,但不一定受視口限制,如果視口裁剪標誌clip爲真,那麼直線將受到視口邊緣截斷;如果clip爲假,即使終點座標或新的當前位置在圖形視口或屏幕極限之外,直線截斷到屏幕極限。
   有兩種線寬及幾種線型可供選擇,也可以自己定義線圖樣。下面分別介紹直線和線型函數。

58. line() 畫線函數
功能: 函數line()使用當前繪圖色、線型及線寬,在給定的兩點間畫一直線。
用法: 該函數調用方式爲void line(int startx,int starty,int endx,int endy);
說明: 參數startx,starty爲起點座標,endx,endy爲終點座標,函數調用前後,圖形狀態下屏幕光標(一般不可見)當前位置不改變。
       此函數相應的頭文件爲graphics.h
返回值: 無
例: 見函數60.linerel()中的實例。

59. lineto() 畫線函數
功能: 函數lineto()使用當前繪圖色、線型及線寬,從當前位置畫一直線到指定位置。
用法: 此函數調用方式爲void lineto(int x,int y);
說明: 參數x,y爲指定點的座標,函數調用後,當前位置改變到指定點(x,y)。
       該函數對應的頭文件爲graphics.h
返回值: 無
例: 見函數60.linerel()中的實例。

60.linerel() 相對畫線函數
功能: 函數linerel() 使用當前繪圖色、線型及線寬,從當前位置開始,按指定的水平和垂直偏移距離畫一直線。
用法: 這個函數調用方式爲void linerel(int dx,int dy);
說明: 參數dx,dy分別是水平偏移距離和垂直偏移距離。
       函數調用後,當前位置變爲增加偏移距離後的位置,例如,原來的位置是(8,6),調用函數linerel(10,18)後,當前位置爲(18,24)。
返回值:無
例: 下面的程序爲畫線函數調用實例:
#include<graphics.h>
void main()
{
   int driver,mode;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   setcolor(15);
   line(66,66,88,88);
   lineto(100,100);
   linerel(36,64);
   getch();
   restorecrtmode();
}

61. setlinestyle() 設置線型函數
功能: setlinestyle() 爲畫線函數設置當前線型,包括線型、線圖樣和線寬。
用法: setlinestyle() 函數調用方式爲void setlinestyle(int stly,unsigned pattern,int width);
說明: 參數style爲線型取值,也可以用相應名稱表示,如表1-10中所示。
       參數pattern用於自定義線圖樣,它是16位(bit)字,只有當style=USERBIT_LINE(值爲1)時,pattern的值纔有意義,使用用戶自定義線圖樣,與圖樣中“1”位對應的像素顯示,因此,pattern=0xFFFF,則畫實線;pattern=0x9999,則畫每隔兩個像素交替顯示的虛線,如果要畫長虛線,那麼pattern的值可爲0xFF00和0xF00F,當style不爲USERBIT_LINE值時,雖然pattern的值不起作用,但扔須爲它提供一個值,一般取爲0。
    參數wigth用來設定線寬,其取值見表1-11,表中給出了兩個值,即1和3,實際上,線寬取值爲2也是可以接受的。
    若用非法參數調用setlinestyle()函數,那麼graphresult()會返回錯誤代碼,並且當前線型繼續有效。
    Turbo C提供的線型與線寬定義在頭文件graphics.h中,表1-10和1-11分別列出了參數的取值與含義。

表1-10  線型
-----------------------------------------------------
   名        稱      取 值         含    義
-----------------------------------------------------
   SOLID_LINE          0             實線
   DOTTED_LINE         1             點線
   CNTER_LINE          2             中心線
   DASHED_LINE         3             虛線
   USERBIT_LINE        4             用戶自定義線型
-----------------------------------------------------

表1-11 線寬
-----------------------------------------------------------
   名         稱            取  值      說   明
-----------------------------------------------------------
   NORM_WIDTH(常寬)           1         一個像素寬(缺省值)
   THICK_WIDTH(加寬)          3         三個像素寬
-----------------------------------------------------------

這個函數的頭文件是graphics.h
返回值: 無
例: 下面的程序顯示了BC中所提供的線型圖樣:
#include<graphics.h>
void main()
{
   int driver,mode;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   for(i=0;i<4;i++)
   {
      setlinestyle(i,0,1);
      line(i*50,200,i*50+60,200)
   }
   getch();
   restorecrtmode();
}

62. getlinesettings() 獲取線型設置函數
功能: 函數getlinesettings() 用當前設置的線型、線圖樣和線寬填 寫linesettingstype型結構。
用法: 函數調用方式爲void getlinesettings(struct linesettingstype *info);
說明: 此函數調用執行後,當前的線型、線圖樣和線寬值被裝入info指向的結構裏,從而可從該結構中獲得線型設置。
   linesettingstype型結構定義如下:
   struct linesettingstype {
      int linestyle;
      unsigned upattern;
      int thickness;
   };
   其中linestyle用於存放線型,線型值爲表1-10中的各值之一。
   upattern用爲裝入用戶自定義線圖樣,這是16位字,每一位等於一個像素,如果哪個位被設置,那麼該像素打開,否則關閉。
   thickness爲線寬值存放的變量,可參見表1-11。
   getlinesettings()函數對應的頭文件爲graphics.h
返回值: 返回的線型設置存放在info指向的結構中。
例: 把當前線型的設置寫入info結構:
   struct linesettingstype info;
   getlinesettings(&info);


63.setwritemode() 設置畫線模式函數
功能: 函數setwritemode() 設置畫線模式
用法: 函數調用方式爲 void setwritemode()(int mode);
說明: 參數mode只有兩個取值0和1,若mode爲0,則新畫的線將覆蓋屏幕上原有的圖形,此爲缺省畫線輸出模式。如果mode爲1,那麼新畫的像素點與原有圖形的像素點先進行異或(XOR)運算,然後輸出到屏幕上,使用這種畫線輸出模式,第二次畫同一圖形時,將擦除該圖形。調用setwritemode()設置的畫線輸出模式隻影響函數line(),lineto(),linerel(),recangle()和drawpoly()。
       setwritemode()函數對應的頭文件是graphics.h
返回值: 無
例: 設置畫線輸出模式爲0:
   setwritemode(0);

(三)、多邊形函數
   
對多邊形,無疑可用畫直線函數來畫出它,但直接提供畫多邊形的函數會給用戶很大方便。最常見的多邊形有矩形、矩形塊(或稱條形)、多邊形和多邊形塊,我們還把長方形條塊也放到這裏一起考慮,雖然它不是多邊形,但它的特例就是矩形(塊)。下面直接介紹畫多邊形的函數。

64. rectangle() 畫矩形函數
功能: 函數rectangle() 用當前繪圖色、線型及線寬,畫一個給定左上角與右下角的矩形(正方形或長方形)。
用法: 此函數調用方式爲void rectangle(int left,int top,int right,int bottom);
說明: 參數left,top是左上角點座標,right,bottom是右下角點座標。如果有一個以上角點不在當前圖形視口內,且裁剪標誌clip設置的是真(1),那麼調用該函數後,只有在圖形視口內的矩形部分才被畫出。
      這個函數對應的頭文件爲graphics.h
返回值: 無
例: 下面的程序畫一些矩形實例:
#include<graphics.h>
void main()
{
   int driver,mode;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   rectangle(80,80,220,200);
   rectangle(140,99,180,300);
   rectangle(6,6,88,88);
   rectangle(168,72,260,360);
   getch();
   restorecrtmode();
}

65. bar() 畫條函數
功能: 函數bar()用當前填充圖樣和填充色(注意不是給圖色)畫出一個指定上左上角與右下角的實心長條形(長方塊或正方塊),但沒有四條邊線)。
用法: bar()函數調用方式爲void bar(int left,int top,int right,int bottom);
說明: 參數left,topright,bottom分別爲左上角座標與右下角座標,它們和調用函數rectangle()的情形相同,調用此函數前,可用setfillstyle()或setfillpattern()設置當前填充圖樣和填充色。
注意此函數只畫沒有邊線的條形,如果要畫有邊線的的條形,可調用下面的函數bar3d()來畫,並將深度參數設爲0,同時topflag參數要設置爲真,否則該條形無頂邊線。
      這 應的頭文件爲graphics.h
返回值: 無
例: 見函數bar3d()中的實例。
  
66.bar3d() 畫條塊函數
功能: 函數bar3d() 使用當前繪圖色、線型及線寬畫出三維長方形條塊,並用當前填充圖樣和填 充色填充該三維條塊的表面。
用法: 此函數調用方式爲void bar3d(int left,int top,int right,int bottom,int depth,int topflag);
說明: 參數left,top,right,bottom分另爲左上角與右下角座標,這與bar()函數中的一樣。參數depth爲條塊的深度,以像素爲單位,通常按寬度的四分之一計算。深度方向通過屏顯縱橫比調節爲約45度(即這時x/y比設置爲1:1)。
參數topflag相當於一個布爾參數,如果設置爲1(真)那麼條塊上放一頂面;若設置爲0(假),則三維條形就沒有頂面,這樣可使多個三維條形疊加在一起。
要使圖形更加美觀,可利用函數floodfill()或setfillpattern()來選擇填充圖樣和填充色(參見本小節(五)填充函數 )。
      bar3d()函數對應的頭文件爲graphics.h
返回值: 無
例: 下面的程序畫一個條形和條塊:
#include<graphics.h>
void main()
{
   int driver,mode;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   setfillstyle(SOLID_FILL,GREEN);
   bar(60,80,220,160);
   setfillstyle(SOLID_FILL,RED);
   bar3d(260,180,360,240,20,1);
   getch();
   restorecrtmode();
}

67. drawpoly() 畫多邊形函數
功能: 函數drawpoly() 用當前繪圖色、線型及線寬,畫一個給定若干點所定義的多邊形。
用法: 此函數調用方式爲void drawpoly(int pnumber,int *points);
說明: 參數pnumber爲多邊形的頂點數;參數points指向整型數組,該數組中是多邊形所有頂點(x,y)座標值,即一系列整數對,x座標值在前。顯然整型數組的維數至少爲頂點數的2倍,在定義了多邊形所有頂點的數組polypoints時,頂點數目可通過計算sizeof(polypoints)除以2倍的sizeof(int)得到,這裏除以2倍的原因是每個頂點有兩個整數座標值。另外有一點要注意,畫一個n個頂點的閉合圖形,頂點數必須等於n+1,並且最後一點(第n+1)點座標必須等於第一點的座標。
   drawpoly()函數對應的頭文件爲grpahics.h
返回值: 無
例: 下面的程序畫一個封閉星形圖與一個不封閉星形圖:
#include<graphics.h>
void main()
{
   int driver,mode;
   static int polypoints1[18]={100,100,110,120,100,130,120,125,140,140,130,120,
   140,110,120,115,100,100};
   static int polypoints2[18]={180,100,210,120,200,130,220,125,240,140,230,120,
   240,110,220,115,220,110};
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   drawpoly(9,polypoints1);
   drawpoly(9,polypoints2);
   getch();
   restorecrtmode();
}

(四)、 圓、弧和曲線函數
   在一個屏幕上畫得很圓的圖形到另一個屏幕上可能被壓扁或拉長,這是因爲每一種顯示卡與之相應的顯示模式都有一個縱橫比。縱橫比是指像素的水平方向大小與垂直方向大小的比值。如VGA顯示卡由於偈素基本上是正方形,所以縱橫比爲1.000。
   爲了保證幾何圖形基本按預計情況顯示在屏幕上,用屏顯的縱橫比來計算和糾正不同硬件及顯示卡產生的畸變。計算縱橫比所需要的水平方向和垂直方向的比例係數可調用函數getaspectratio()獲得。

68. getaspectratio()獲取縱橫比函數
功能: 函數getaspectratio()返回x方向和y方向的比例係數,用這兩個整型值可計算某一特定屏顯的縱橫比。
用法: 此函數調用方式爲void getaspectratio(int xasp,int yasp);
說明: 參數xasp指向的變量存放返回的x方向比例係數;參數yasp指向的變量存放返回的y方向比例係數。通常y方向比例係數爲10 000, x方向比例係數不大於10 000(這是因爲大多數屏幕像素高比寬長)。
   注意縱橫比自動用作下面函數arc(),circle()和pieslice()中的標尺因子,使屏幕上圓或弧正常顯示。但用ellipse()函數畫橢圓必須調用本函數獲取縱橫比作爲標尺因子,否則不予調整。縱橫比可用於其它幾何圖形,目的是校正和顯示圖形。
   getaspectratio()函數對應的頭文件爲graphics.h
返回值: 返回x與y方向比例係數分別存放在xasp和yasp所指向的變量中。
例: 下面的程序顯示縱橫比:
   int xasp,yasp;
   float aspectratio;
   getaspectratio(&xasp,&yasp);
   aspectratio=xasp/yasp;
   printf("aspect ratio: %f",aspectratio);

69. circle()畫圓函數
功能: 函數circle()使用當前繪圖色並以實線畫一個完整的圓。
用法:該函數調用方式爲void circle(int x,int y,int radius);
說明: 參數x,y爲圓心座標,radius爲圓半徑,用像素個素表示。注意,調用circle()函數畫圓時不用當前線型。
   不同於ellipse()函數,只用單個半徑radius參數調用circle()函數,故屏顯縱橫比可以自動調節,以產生正確的顯示圖。
   此函數對應的頭文件爲graphics.h
返回值: 無
例: 畫六個同心圓,圓心在(100,100)。
#include<graphics.h>
void main()
{
   int driver,mode;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   circle(100,100,10);
   circle(100,100,20);
   circle(100,100,30);
   circle(100,100,40);
   circle(100,100,50);
   circle(100,100,60);
   getch();
   restorecrtmode();
}

70. arc() 畫圓弧函數
功能: 函數arc()使用當前繪圖色並以實線畫一圓弧。
用法: 函數調用方式爲void arc(int x,int y,int startangle,int endangle,int radius);
說明: 參數x,y爲圓心座標,startangle與endangle分別爲起始角與終止角,radius爲半徑。圓心座標和半徑以像素個數給出,起始角和終止角以度爲單位,0度位於右邊,90度位於頂部,180度位於左邊,底部是270度。同往常一樣,360度與0度重合。角度按逆時針方向增加,但並不要求終止角一定比起始角大。例如指定300度和90度分別爲起始角和終止角,與指定300度和450度分別爲起始角和終止角可畫出相同的弧。大於360度可作爲參數,它將被化到0度 ̄360度範圍裏。函數arc()能畫封閉圓,只要取起始角爲0度,終止角爲360度即可。此函數中,屏顯縱橫比可自動調節。
   arc()函數對應的頭文件爲graphics.h
返回值: 無
例: 以(200,200)爲圓心,100爲半徑,從0度到120度畫圓弧:
#include<graphics.h
void main()
{
   int driver,mode;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   setcolor(WHITE);
   arc(200,200,0,120,100);
   getch();
   restorecrtmode();
}

71. ellipse()畫橢圓弧函數
功能: 函數ellipse()使用當前繪圖色畫一橢圓弧。
用法: 該函數調用方式爲void ellipse(int x,int y,int startangle,int endangle,
                                       int xradius,int yradius);
說明: 參數x,y爲橢圓中心座標,startangle和endangle爲給定的起始角和終止角,xradius與yradius爲橢圓的x軸半徑與y軸半徑,如果startangle爲0 ,endangle等於360度,那麼畫出的是個完整的橢圓。ellipse()函數不同於arc()和circle()函數,屏顯縱橫比不能自動調節。若需要的是成比例的半徑而不是特定的像素距離,則y軸距離必須調節爲yradius*aspectratio(y軸半徑乘以縱橫比)。
   此函數對應的頭文件爲graphics.h
返回值: 無
例: 在屏幕上畫一個雞蛋形的橢圓。
#include<graphics.h>
void main()
{
   int driver,mode;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   ellipse(200,100,0,360,80,40);
   getch();
   restorecrtmode();
}

72. fillellipse() 畫橢圓區函數
功能: 函數fillellipse()使用當前繪圖色畫一橢圓,然後用當前填充色圖樣和填充色填充所畫的橢圓。
用法: 此函數調用方式爲void fillellipse(int x,int y,int xradius,int yradius);
說明: 參數x,y爲橢圓中心座標,xradius,yradius爲水平軸半徑和垂直軸半徑
       這個函數對應的頭文件爲graphics.h
返回值: 無
例: 畫一填充橢圓:
#include<graphics.h>
#include<stdio.h>
#define R 60
void main()
{
   
int driver,mode;
   int xasp,yasp;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   fillellipse(getmaxx()/2,getmaxy()/2,66,44);
   
getaspectratio(&xasp,&yasp);
   fillellipse(R,R,R,R*(long)xasp/(long)yasp);
   getch();
   closegraph();
}

73. pieslice() 畫扇區函數
功能: 函數pieslice()使用當前繪圖色畫一圓弧,並把弧兩端與圓心分別連一直線段(即半徑),然後用當前填圖樣和填充色進行填充,即得扇區。
用法: 這個函數調用方式爲void pieslice(int x,int y,int startangle,int endangle,int radius);
說明: 函數pieslice()的操作類似於arc()函數(即同調用參數一樣,只是函數名不同),因此調用此函數的詳細說明參見函數arc()的相應內容。該函數對屏顯縱橫比能自動調節進行補償。
   pieslice()函數對應的頭文件爲graphics.h
返回值:無
例: 顯示一個扇形圖,每45度爲一個不同的扇區:
#include<graphics.h>
void main()
{
   int driver,mode;
   int i,start,end;
   driver=DETECT;
   mode=0;
   initgraph(&driver,mode,"");
   start=0;
   end=45;
   for(i=0;i<8;i++)
   {
      setfillstyle(SOLID_FILL,i);
      pieslice(260,200,start,end,100);
      start+=45;
      end+=45;
   }
   getch();
   restorecrtmode();
}


74. sector() 畫橢圓扇區函數
功能: 函數sector()先用當前繪圖色畫橢圓扇形輪廓,然後用當前填充圖樣和填充色進行填充,即得橢圓扇區。
用法: 該函數調用方式爲void sector(int x,int y,int startangle,int endangle,int xradius,int yradius);
說明: 參數x,y爲橢圓中心座標,startangle和endangle爲起始角與終止角,xradius與yradius是水平軸半徑和垂直軸半徑即長短軸。當startangle爲0,endangle爲360度時,調用此函數可畫得一個完整的橢圓區。角度增加方向爲反時針方向。設定填充圖樣和填充色,用setfillstyle()或setfillpattern()函數,若畫輪廓線或填充扇區出現錯誤,則graphresult()函數返回值-6。對屏顯縱橫比,sector()函數不能自動調節補償。
返回值: 無
例: 畫出兩個橢圓扇區:
#include<graphics.h>
#include<stdio.h>
#define R 80
void main()
{
   int driver,mode;
   int xasp,yasp;
   initgraph(&driver,&mode,"");
   sector(getmaxx()/2,getmaxy()/2,0,656,R,R);
   getaspectratio(&xasp,&yasp);
   setctor(getmaxx()/2,getmaxy()/2,180,135,R,R*(long)xasp/(long)yasp);
   getch();
   closegraph();
}

75. getarccoords()獲取圓弧座標函數
功能: 函數getarccoords()將最後一次調用arc()或ellipse()畫的圓弧或橢圓弧的起終點座標和中心座標填入arccoordstype型結構裏,進而從該結構中獲取這些座標值。
用法: getarccoords()函數調用方式爲void getarccoords(struct arccoordstype *coordsp);
說明: 調用此函數填寫coordsp指向的結構,從而獲得起終點座標和中心座標值。它們可用於畫弦、半徑以及其它與圓弧端點相連的直線等。pieslice()函數就要用到這些值。如果最後一次調用的函數是circle(),那麼getarccoords()將返回圓心座標和起終點座標即圓的位置。
   arccoordstype型結構定義如下:
   struct arccoordstype {
      int x,y;
      int xstart,ystart,xend,yend;
   };
   其中,x,y存放中心座標;xstart,ystart,xend,yend分別存放起終點座標。
   值得注意的是,結構裏起終點(xstart,ystart)與(xend,yend)座標是像素值,不是角度值,這和調用arc()或ellipse()函數所用的不一樣。當然中心座標(x,y)與調用函數時所用的是一樣的。
   這個函數的頭文件是graphics.h
返回值: 返回最後一次調用圓或橢圓函數的相應起終點與中心座標值,並存放在coordsp指向的結構裏。
例: 下面的程序畫圓心在(100,100)的四分之一圓弧,然後於弧兩端點之間連一直線。
#include<graphics.h>
void main()
{
   int driver,mode;
   struct arccoordstype arcinfo;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   arc(100,100,0,90,88);
   getarccoords(&arcinfo);
   line(arcinfo.xstart,arcinfo.ystart,arcinfo.xend,arcinfo.yend);
   getch();
   restorecrtmode();
}

(五)、 填充函數
   前面已經涉及到了用填充圖樣和填充色填充圖形的問題,如調用pieslice()畫扇區就要用填充圖樣與填充色來填充區域。那麼怎樣設置填充圖樣和填充色呢?我們只要簡單地學習並練習一下就會掌握其方法。下面介紹用於設置填圖樣與填充色、建立用戶自己的填充圖樣與填充封閉區域的幾個常用函數。

76. setfillstyle() 設置填充圖樣和顏色函數
功能:setfillstyle()設置填充圖樣和顏色函數
功能: 函數setfillstyle()爲各種圖形函數設置填充圖樣和顏色。
用法: 函數調用方式爲void setfillstyle(int pattern,int color);
說明: 參數pattern的值爲填充圖樣,它們在頭文件graphics.h中定義,詳見表1-12所示。
   參數color的值是填充色,它必須爲當前顯示模式所支持的有效值。
   填充圖樣與填充色是獨立的,可以是不同的值。

表1-12 填充圖樣
-------------------------------------------------------------------
   填充圖樣符號名         取值            說明
-------------------------------------------------------------------
   EMPTy_FILL               0         用背景色填充區域(空填)
   SOLID_FILL               1         用實填充色填充(實填)
   LINE_FILL                2         ----填充
   LTSLASH_FILL             3         ///填充
   SLASH_FILL               4         ///用粗線填充
   BKSLASH_FILL             5         ///用粗線填充
   LTBKSLASH_FILL           6         ///填充
   HATCH_FILL               7         網格線填充
   xHATCH_FILL              8         斜網格線填充
   INTEREAVE_FILL           9         間隔點填充
   WIDE_DOT_FILL            10        大間隔點填充
   CLOSE_DOT_FILL           11        小間隔點填充
   USER_FILL                12        用戶定義圖樣填充
-------------------------------------------------------------------

   除了EMPTy_FILL,所有填充圖樣都使用當前填充色,填充圖樣USER_FILL只有在用函數setfillpattern()已經建立一個用戶定義的填充圖樣後才能使用。
   此函數對應的頭文件爲graphics.h
返回值: 無
例: 下面的程序用HATCH_FILL填充一個矩形:
#include<graphics.h>
void main()
{
   int driver,mode;
   driver=DETECT;
   mode=0;
   initgraph(&driver,mode,"");
   setcolor(GREEN);
   rectangle(80,200,200,300);
   setfillstyle(HATCH_FILL,RED);
   floodfill(160,240,GREEN);
   getch();
   restorecrtmode();
}

77. setfillpattern() 設置用戶圖樣函數
功能: 函數setfillpattern() 設置用戶的填充圖樣以供fllodfill(),fillpoly()填充函數等使用。
用法: 此函數調用方式爲void setfillpattern(char *pattern,int color);
說明: 參數color設置填充圖樣的顏色。參數pattern指向一字符數組,該數組至少8個字節長,它定義了一個8像素*8像素的用戶填充圖樣。例如:
   char diamond[8]={0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00};
   diamond爲8個字節的數組,每個字節對應於填充圖樣中的8個像素,字節中的1位,畫出一個由color設定顏色的像素,字節中的0位則不畫。實際上,diamond數組定義了一個7*7的小鑽石圖樣,右邊和底部都留有一個像素的邊緣。
   調用setfillpattern()設置用戶填充圖樣後,必須調用setfilstyle()函數,使USER_FILL值成爲當前填充圖樣。
   這個函數對應的頭文件爲graphics.h
返回值: 無
例:建立一個用戶填充圖樣,並用它填充一個矩形:
#include<graphics.h>
void main()
{
   int driver,mode;
   static char p[8]={10,20,30,40,50,60,70,80};
   driver=DETECT;
   mode=0;
   initgraph(&driver,mode,"");
   setcolor(GREEN);
   rectangle(80,200,220,300);
   setfillpattern(p,RED);
   floodfill(160,260,GREEN);
   getch();
   restorecrtmode();
}

78. floodfill() 填充閉域函數
功能: 函數floodfill()用當前填充圖樣和填充色填充一個由特定邊界顏色(通常是當前繪圖色)定義的有界封閉區域。
用法: 該函數調用方式爲void floodfill(int x,int y,int bordercolor);
說明: 這裏參數(x,y)爲指定填充區域中的某點,如果點(x,y)在該填充區域之外,那麼外部區域將被填充,但受圖形視口邊界的限制。如果直線定義的區域出現間斷,那麼將導致泄漏,即使很小的間斷,也將導致泄漏。也就是說,間斷將引起區域外被填充。
   參數bordercolor爲閉區域邊界顏色,若可能的話,建議儘量用下面函數fillpoly()代替floodfill(),以便和將來的版本保持兼容。
   如果出錯,graphresult()函數將返回錯誤代碼-7(flood填充內存不足)。
   此函數對應的頭文件爲graphics.h
返回值: 無
例: 用floodfill() 函數填充一個具有交叉陰影線的品紅色橢圓:
#include<graphics.h>
void main()
{
   int driver,mode;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   ellipse(188,88,0,360,100,60);
   setfillstyle(HATCH_FILL,MAGENTA);
   floodfill(188,88,WHITE);
   getch();
   restorecrtmode();
}

79. fillpoly() 填充多邊形函數
功能: 函數fillpoly()用當前繪圖色、線型及線寬畫出給定點的多邊形,然後用當前填充圖樣和填充色填充這個多邊形。
用法: 此函數調用方式爲void fillpoly(int pointnum,int *points);
說明: fillpoly()的調用形式與drawpoly()的一樣,其參數含義相同。該函數中pointnum爲所填充多邊形的頂點數,points指向存放所有頂點座標的整型數組。有時頂點數目是通過過計算sizeof(整型數組)除以兩倍的sizeof(int)然後得到的,之所以除以兩倍的sizeof(int)是因爲每個頂點需要兩個整型座標。
注意,fillpoly()是通過連接起點和終點將圖形封閉起來,然後填充被包圍的區域。與floodfill()不同的是,fillpoly()所用的填充方法不依靠邊界連續的輪廓來確定填充區域。這樣間斷的線型是允許的,並且可以很簡單地填充多邊形確定的區域,包括在新的邊界範圍內任何其它圖形上重畫。如果出錯,graphresult()函數將返回錯誤代碼-6(Scan填充內存不足)。
   這個函數對應的頭文件爲graphics.h
返回值: 無
例:用紅色間隔點填充一個正方形:
#include<graphics.h>
void main()
{

   int driver,mode;  
   static int points[]={100,100,100,200,200,200,100,100};
   driver=DETECT;
   mode=0;
   initgraph(&driver,mode,"");
   setfillstyle(INTERLEAVE_FILL,RED);
   fillpoly(4,points);
   getch();
   restorecrtmode();
}

80. getfillsettings() 獲取填充設置函數
功能: 函數getfillsettings()將當前填充圖樣值(符號名或等價值)和填充顏色值(符號名或等價值)填入fillsettingstyle型結構裏,從而從該結構中獲得當前填充設置(填充圖樣和填充色)。
用法: 這個函數調用方式爲void getfillsettings(struct fillsettingstype *info);
說明: 函數裏fillsettingstype 型結構定義如下:
   struct fillsettingstype {
         int pattern;
         int color;
   };
   注意,結構中變量pattern只用於存取一個預先定義的填充圖樣值,而不是填充圖樣元素,填充圖樣及等價值在前面表1-12中已經列出。結構變量color用來存儲填充顏色值,它是當前顯示模式的有效顏色值之一。
   getfillsettings()函數相應的頭文件是graphics.h
返回值:返回當前填充圖樣和填充色的值,並裝入info指向的結構裏。
例: 下面的程序把當前填充圖樣和填充色的值寫入fillinfo結構中:
   struct fillsettingstype fillinfo;
   getfillsettings(&fillinfo);

81. getfillpattern() 獲取用戶圖樣設置函數
功能: 函數getfillpattern()返回上一次調用setfillpattern()設置的用戶定義的填充圖樣。
用法: 此函數調用方式爲void getfillpattern(char *pattern);
說明: 函數一旦調用,就會把定義當前用戶填充圖樣的8個字節填入pattern所指向的數組,該數組必須至少8字節長,用戶圖樣以8個8位字節的模式排列,如果還沒有調用setfillpattern()設置用戶定義的填充圖樣,那麼函數將填入數組元素的值全爲0xff。
   getfillpattern()函數對應的頭文件爲graphics.h
返回值: 返回用戶定義填充圖樣的8個字節數據(注意不是填充圖樣元素),並存放在pattern指向的數組裏。
例: 顯示組成當前用戶填充圖樣的各字節內容:
#include<graphics.h>
void main()
{
   int driver,mode;
   char fp[8];
   int i;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   getfillpattern(fp);
   for(i=0;i<8;i++) printf("%d",fp[i]);
   getch();
   restorecrtmode();
}


(六)、圖像函數
   圖像複製、擦除以及一般對屏幕圖像的操作,這對應用程序是非常有用的,對動畫製作是必不可少的。BC提供了以下幾個圖像操作函數。

82. imagesize() 圖像存儲大小函數
功能: 函數imagsize()返回存儲一塊屏幕圖像所需的內存大小(即字節數)。
用法: 此函數調用方式爲unsigned imagsize(int left,int top,int right,int bottom);
說明: 參數(left,top)爲所定義的一塊圖像屏幕左上角,(right,bottom)爲其右下角。
   函數調用執行後,返回存儲該塊屏幕所需要的字節數。如果所需要字節數大於64KB,那麼將返回-1。imagesize()函數一般與下面getimage()函數聯用。
   這個函數對應的頭文件爲graphics.h
返回值: 返回一塊圖像屏幕存儲所需的字節數,如果大於64KB,則返回-1。
例: 確定左上角(10,10)與右下角(100,100)所定義的屏幕圖像所需的字節數:
   unsigned size;
   size=imagesize(10,10,100,100);

83. getimage() 保存圖像函數
功能: 函數getimage()保存左上角與右下角所定義的屏幕上像素圖形到指定的內存區域。
用法: 該函數調用方式爲void getimage(int left,int top,int right,int bottom,void *buf);
說明: 函數中參數(left,top)爲要保存的圖像屏幕的左上角,(right,bottom)爲其右下角,buf指向保存圖像的內存地址。調用getimage()保存屏幕圖像,可用imagesize()函數確定保存圖像所需字節數,再用malloc()函數分配存儲圖像的內存(內存分配必須小於64KB),還可以用下面函數putimage()輸出getimage()保存的屏幕圖像。
   這個函數對應的頭文件爲graphics.h
返回值: 無
例: 把帶有兩對角線的矩形拷貝到屏幕其它位置上:
#include<graphics.h>
#include<stdlib.h>
#include<conio.h>
void main()
{
   int driver,mode;
   unsigned size;
   void *buf;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   setcolor(15);
   rectangle(20,20,200,200);
   setcolor(RED);
   line(20,20,200,200);
   setcolor(GREEN);
   line(20,200,200,20);
   getch();
   size=imagesize(20,20,200,200);
   if(size!=-1){
      buf=malloc(size);
      if(buf){
         getimage(20,20,200,200,buf);
         putimage(100,100,buf,COPY_PUT);
         putimage(300,50,buf,COPY_PUT);
      }
   }
   outtext("press a key");
   getch();
   restorecrtmode();
}

84. putimage() 輸出圖像函數
功能: 函數putimage()將一個先前保存在內存中的圖像輸出到屏幕上。
用法: 此函數調用方式爲void putimage(int left,int top,void *buf,int ops);
說明: 參數(left,top)爲輸出屏幕圖像的左上角,即輸出圖像的起始位置。buf指向要輸出的內存中圖像。參數ops控制圖像以何種方式輸出到屏幕上。表1-13給出了圖像輸出方式。

表1-13  圖像輸出方式
--------------------------------------------------------------------
   輸出方式符號名      取值               含     義
--------------------------------------------------------------------
   COPy_PUT              0         圖像輸出到屏幕上,取代原有圖像
   xOR_PUT               1         圖像和原有像素作異或運算
   OR_PUT                2         圖像和原有像素作或運算
   AND_PUT               3         圖像和原有像素作與運算
   NOT_PUT               4         把求反的位圖像輸出到屏幕上
--------------------------------------------------------------------

1) COPy_PUT輸出方式
   圖像中每個像素都直接繪製到屏幕上,取代原有圖像像素,包括空白的圖像像素(背景)。完全空白的圖像可以用來擦除其它圖像或屏幕的一部分。但通常選擇xOR_PUT輸出方式擦除原有圖像。
2)xOR_PUT輸出方式
   原有屏幕每個像素與相應的圖像字節作“異或”運算,其結果畫到屏幕上。當某一圖像和屏幕上原有圖像作“異或”運算時,屏幕顯示的是兩個圖像的合成。若相同的圖像作異或運算,將有效地擦除該圖像,留下原始屏幕。這種輸出方式,對動畫製作是非常有用的。
3)OR_PUT輸出方式
   每個圖像字節和相應的屏幕像素作“或”運算,再將結果畫到屏幕上,這種輸出方式也叫“兩者取一”。記住,像素中的每位和圖像中的每位作“或”運算,這樣所得結果是背景和圖像的彩色合成圖像。
4)AND_PUT輸出方式
   選擇AND_PUT圖像輸出方式時,屏幕像素和圖像字節中都顯示的位,運算後仍顯示,例如,星圖像中的空白背景擦除了方塊輪廓以及填充色,只有星圖像覆蓋着的方塊留下,即運算後,顯示兩者相同的圖像。
5)NOT_PUT輸出方式
   NOT_PUT輸出方式,除了把圖像的每位求反---圖像中所有黑的像素(0000)變成了白色(1111),其它方面與COPy_PUT相同。背景圖像被重畫後將消失。
   putimage()函數對應的頭文件爲garphics.h
返回值: 無
例: 下面的程序說明了imagesize(),getimage()和putimage()函數的調用方法:
#include<graphics.h>
#include<conio.h>
#include<stdlib.h>
void box(int ,int,int,int,int);
void main()
{
   int driver,mode;
   unsigned size;
   void *buf;
   driver=DETECT;
   mode=0;
   initgraph(&driver,&mode,"");
   box(20,20,200,200,15);
   setcolor(RED);
   line(20,20,200,200);
   setcolor(GREEN);
   line(20,200,200,20);
   getch();
   size=imagesize(20,20,200,200);
   if(size!=-1)
   {
      buf=malloc(size);
      if(buf){
         getimage(20,20,200,200,buf);
         putimage(120,120,buf,COPY_PUT);
         putimage(280,60,buf,COPY_PUT);
      }
   }
   outtext("Press a key");
   getch();
   restorecrtmode();
}
void box(int startx,int starty,int endx,int endy,int color)
{
   setcolor(color);
   rectangle(startx,starty,endx,endy);
}
圖像函數是對屏幕圖像操作進行討論的,但對屏幕圖形同樣適用。實際上,屏幕圖形也是一種特定的屏幕圖像,它可稱爲外形屏幕圖像或稱輪廓屏幕圖像。因此圖像與圖形不必區分。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章