PHP 5.0創(chuàng)建圖形的實(shí)用方法完整篇第2/3頁(yè)
更新時(shí)間:2008年01月26日 19:26:30 作者:
PHP 5.0創(chuàng)建圖形的實(shí)用方法完整篇
在運(yùn)行這個(gè)程序時(shí),test.png 文件應(yīng)該如圖 5 所示。
圖5. 紅圓在黑方框之后

現(xiàn)在修改下面的代碼:
$gobjs []= new Oval( 200, "red", 50, 50, 150, 150 ); $gobjs []= new Rectangle( 100, "black", 100, 100, 300, 300 ); |
再次運(yùn)行這個(gè)代碼,突然這個(gè)橢圓就在這個(gè)方框上面了,如圖 6 所示。
圖6. 紅圓現(xiàn)在在黑方框上面了

紅圓現(xiàn)在就出現(xiàn)在黑方框上面了,盡管它是先創(chuàng)建的,也是首先添加到數(shù)組中的。這就是 z 值的實(shí)際價(jià)值:您可以按照任何順序來(lái)創(chuàng)建對(duì)象,并可以通過(guò)調(diào)整每個(gè)對(duì)象的 z 值來(lái)調(diào)整彼此之間的相對(duì)位置。
在這段代碼中,z 值排序是在這個(gè)庫(kù)之外實(shí)現(xiàn)的。讓我們通過(guò)創(chuàng)建一個(gè)新容器對(duì)象 Group 來(lái)實(shí)現(xiàn)這種功能,其中保存了一組 GraphicsObject 對(duì)象。Group 對(duì)象然后再處理排序的問(wèn)題。
Group 類的代碼如清單 5 所示。
清單 5. Group 類
function zsort( $a, $b )
{
if ( $a->z() < $b->z() ) return -1;
if ( $a->z() > $b->z() ) return 1;
return 0;
}
class Group extends GraphicsObject
{
private $z;
protected $members = array();
public function __construct( $z )
{
$this->z = $z;
}
public function add( $member )
{
$this->members []= $member;
}
public function render( $ge )
{
usort( $this->members, "zsort" );
foreach( $this->members as $gobj )
{
$gobj->render( $ge );
}
}
public function z() { return $this->z; }
}
|
Group 對(duì)象的任務(wù)是保持一個(gè)對(duì)象數(shù)組,然后在畫圖時(shí),逐個(gè)對(duì)對(duì)象zo進(jìn)行排序和畫圖。
更新后的測(cè)試代碼如清單 6 所示。
清單 6. 更新后的測(cè)試代碼
<?php require_once( "glib.php" ); $ge = new GraphicsEnvironment( 400, 400 ); $ge->addColor( "black", 0, 0, 0 ); $ge->addColor( "red", 255, 0, 0 ); $ge->addColor( "green", 0, 255, 0 ); $ge->addColor( "blue", 0, 0, 255 ); $g1 = new Group( 0 ); $g1->add( new Oval( 200, "red", 50, 50, 150, 150 ) ); $g1->add( new Rectangle( 100, "black", 100, 100, 300, 300 ) ); $g1->render( $ge ); $ge->saveAsPng( "test.png" ); ?> |
現(xiàn)在所有的客戶機(jī)需要做的是創(chuàng)建一個(gè) Group 對(duì)象。它會(huì)處理排序和其他操作。
[NextPage]
創(chuàng)建 viewport
viewport 是一個(gè)人造的坐標(biāo)系統(tǒng),可以轉(zhuǎn)換成圖像的物理坐標(biāo)系統(tǒng)。viewport 的擴(kuò)展可以是您希望的任何東西。例如,x 和 y 軸的起點(diǎn)和終點(diǎn)可以是 -2 和 2,這樣 viewport 坐標(biāo)平面的中心就是 0, 0。這對(duì)于三角圖形(例如 sin 和 cosine)來(lái)說(shuō)是很好的一個(gè) viewport?;蛘撸@個(gè) viewport 也可以是不對(duì)稱的,其中 y 值的范圍從 -1 到 1,x 值的范圍是從 0 到 10,000,這取決于您的需要。
這個(gè) viewport 的其他值可以確保構(gòu)建一個(gè) 400X400 的圖像所采用的邏輯與構(gòu)建一個(gè) 4000X2000 的圖像所采用的邏輯是相同的。代碼負(fù)責(zé)向這個(gè) viewport 中寫入數(shù)據(jù),然后這個(gè) viewport 自動(dòng)實(shí)現(xiàn)到圖像的物理尺寸的自動(dòng)映射。
要讓您的 viewport 正常工作,您需要將這個(gè) viewport 的范圍從 0,0 修改為 1,1,這可以讓圖形對(duì)象回調(diào)圖形環(huán)境,從而將 viewport 的坐標(biāo)轉(zhuǎn)換成物理坐標(biāo)。您可以將所有的代碼都放到 BoxObject 基類中進(jìn)行簡(jiǎn)化。
圖 7 顯示了有關(guān)新添加的代碼的兩個(gè)內(nèi)容。首先是添加的 tx 和 ty 方法,這會(huì)將 x 和 y 坐標(biāo)從 viewport 轉(zhuǎn)換成物理圖像的坐標(biāo)。第二個(gè)是對(duì) BoxObject 增加了 draw 方法,它的派生類應(yīng)該用來(lái)進(jìn)行制圖。BoxObject 在 render 方法中實(shí)現(xiàn) viewport 的轉(zhuǎn)換,并使用物理坐標(biāo)來(lái)調(diào)用 draw 方法。使用這種方法,Line、Oval 和 Rectangle 類都可以利用 viewport 坐標(biāo),而不需要擔(dān)心坐標(biāo)轉(zhuǎn)換的問(wèn)題。
圖 7. 所添加的圖形環(huán)境 viewport 轉(zhuǎn)換

這個(gè)新庫(kù)的代碼如清單 7 所示:
清單 7. 具有 viewport 支持的圖形庫(kù)
<?php
class GraphicsEnvironment
{
public $width;
public $height;
public $gdo;
public $colors = array();
public function __construct( $width, $height )
{
$this->width = $width;
$this->height = $height;
$this->gdo = imagecreatetruecolor( $width, $height );
$this->addColor( "white", 255, 255, 255 );
imagefilledrectangle( $this->gdo, 0, 0,
$width, $height,
$this->getColor( "white" ) );
}
public function width() { return $this->width; }
public function height() { return $this->height; }
public function addColor( $name, $r, $g, $b )
{
$this->colors[ $name ] = imagecolorallocate(
$this->gdo,
$r, $g, $b );
}
public function getGraphicObject()
{
return $this->gdo;
}
public function getColor( $name )
{
return $this->colors[ $name ];
}
public function saveAsPng( $filename )
{
imagepng( $this->gdo, $filename );
}
public function tx( $x )
{
return $x * $this->width;
}
public function ty( $y )
{
return $y * $this->height;
}
}
abstract class GraphicsObject
{
abstract public function render( $ge );
abstract public function z();
}
function zsort( $a, $b )
{
if ( $a->z() < $b->z() ) return -1;
if ( $a->z() > $b->z() ) return 1;
return 0;
}
class Group extends GraphicsObject
{
private $z;
protected $members = array();
public function __construct( $z )
{
$this->z = $z;
}
public function add( $member )
{
$this->members []= $member;
}
public function render( $ge )
{
usort( $this->members, "zsort" );
foreach( $this->members as $gobj )
{
$gobj->render( $ge );
}
}
public function z() { return $this->z; }
}
abstract class BoxObject extends GraphicsObject
{
protected $color;
protected $sx;
protected $sy;
protected $ex;
protected $ey;
protected $z;
public function __construct( $z, $color, $sx, $sy, $ex, $ey )
{
$this->z = $z;
$this->color = $color;
$this->sx = $sx;
$this->sy = $sy;
$this->ex = $ex;
$this->ey = $ey;
}
public function render( $ge )
{
$rsx = $ge->tx( $this->sx );
$rsy = $ge->ty( $this->sy );
$rex = $ge->tx( $this->ex );
$rey = $ge->ty( $this->ey );
$this->draw( $rsx, $rsy, $rex, $rey,
$ge->getGraphicObject(),
$ge->getColor( $this->color ) );
}
abstract public function draw( $sx, $sy,
$ex, $ey, $gobj, $color );
public function z() { return $this->z; }
}
class Line extends BoxObject
{
public function draw( $sx, $sy, $ex, $ey,
$gobj, $color )
{
imageline( $gobj, $sx, $sy, $ex, $ey,
$color );
}
}
class Rectangle extends BoxObject
{
public function draw( $sx, $sy, $ex, $ey,
$gobj, $color )
{
imagefilledrectangle( $gobj, $sx, $sy,
$ex, $ey, $color );
}
}
class Oval extends BoxObject
{
public function draw( $sx, $sy, $ex, $ey,
$gobj, $color )
{
$w = $ex - $sx;
$h = $ey - $sy;
imagefilledellipse( $gobj,
$sx + ( $w / 2 ), $sy + ( $h / 2 ),
$w, $h, $color );
}
}
?>
|
GraphicsEnvironment 類中的 viewport 轉(zhuǎn)換代碼是高亮顯示的,正如 GraphicsObject 中的 render 代碼一樣,這會(huì)回調(diào)圖形環(huán)境來(lái)進(jìn)行坐標(biāo)轉(zhuǎn)換的工作。
相關(guān)文章
PHP 在5.1.* 和5.2.*之間 PDO數(shù)據(jù)庫(kù)操作中的不同之處小結(jié)
今天發(fā)現(xiàn)php5.1.*和php5.2.*在數(shù)據(jù)庫(kù)預(yù)編譯代碼執(zhí)行的時(shí)候出現(xiàn)差異2012-03-03
php+Mysqli利用事務(wù)處理轉(zhuǎn)賬問(wèn)題實(shí)例
這篇文章主要介紹了php+Mysqli利用事務(wù)處理轉(zhuǎn)賬問(wèn)題的方法,實(shí)例分析了php+mysqli處理事務(wù)的提交與回滾的技巧,需要的朋友可以參考下2015-02-02
php 獲取當(dāng)前訪問(wèn)的url文件名的方法小結(jié)
php下獲取當(dāng)前訪問(wèn)的文件名的代碼小結(jié),大家可以根據(jù)需要選擇。2010-02-02
PHP動(dòng)態(tài)生成指定大小隨機(jī)圖片的方法
這篇文章主要介紹了PHP動(dòng)態(tài)生成指定大小隨機(jī)圖片的方法,涉及PHP根據(jù)傳入?yún)?shù)動(dòng)態(tài)生成圖片的相關(guān)技巧,需要的朋友可以參考下2016-03-03
PHP實(shí)現(xiàn)表單提交數(shù)據(jù)的驗(yàn)證處理功能【防SQL注入和XSS攻擊等】
這篇文章主要介紹了PHP實(shí)現(xiàn)表單提交數(shù)據(jù)的驗(yàn)證處理功能,可實(shí)現(xiàn)防SQL注入和XSS攻擊等,涉及php字符處理、編碼轉(zhuǎn)換相關(guān)操作技巧,需要的朋友可以參考下2017-07-07
PHP中unset,array_splice刪除數(shù)組中元素的區(qū)別
php中刪除數(shù)組元素是非常的簡(jiǎn)單的,但有時(shí)刪除數(shù)組需要對(duì)索引進(jìn)行一些排序要求我們會(huì)使用到相關(guān)的函數(shù),這里我們來(lái)介紹使用unset,array_splice刪除數(shù)組中的元素區(qū)別吧2014-07-07
PHP生成各種隨機(jī)驗(yàn)證碼的方法總結(jié)【附demo源碼】
這篇文章主要介紹了PHP生成各種隨機(jī)驗(yàn)證碼的方法,結(jié)合具體實(shí)例形式總結(jié)分析了php常用的生成驗(yàn)證碼操作相關(guān)技巧,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2017-06-06

