summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxue <>2007-08-29 19:57:50 +0000
committerxue <>2007-08-29 19:57:50 +0000
commitdd02492f08248bf9b53a20b54a3d49a9f78fc0ad (patch)
tree31ae15e2ed59a6279f09bf639d367d1844e12055
parent9d13a92291fad0a5a5fd46179149654cb357c9d0 (diff)
finished TCaptcha.
-rw-r--r--.gitattributes3
-rw-r--r--demos/quickstart/protected/pages/Controls/Captcha.page39
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TCaptcha/Home.page32
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TCaptcha/Home.php27
-rw-r--r--demos/quickstart/protected/pages/Controls/Standard.page4
-rw-r--r--demos/quickstart/protected/pages/GettingStarted/NewFeatures.page2
-rw-r--r--framework/Exceptions/messages/messages.txt12
-rw-r--r--framework/Web/UI/WebControls/TCaptcha.php81
-rw-r--r--framework/Web/UI/WebControls/assets/captcha.php169
9 files changed, 332 insertions, 37 deletions
diff --git a/.gitattributes b/.gitattributes
index d605adf9..ccaebf65 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1271,6 +1271,7 @@ demos/quickstart/protected/pages/Configurations/Templates3.page -text
demos/quickstart/protected/pages/Configurations/UrlMapping.page -text
demos/quickstart/protected/pages/Construction.page -text
demos/quickstart/protected/pages/Controls/Button.page -text
+demos/quickstart/protected/pages/Controls/Captcha.page -text
demos/quickstart/protected/pages/Controls/CheckBox.page -text
demos/quickstart/protected/pages/Controls/ClientScript.page -text
demos/quickstart/protected/pages/Controls/ClientScriptLoader.page -text
@@ -1318,6 +1319,8 @@ demos/quickstart/protected/pages/Controls/Samples/TBulletedList/Home.php -text
demos/quickstart/protected/pages/Controls/Samples/TBulletedList/bullet.gif -text
demos/quickstart/protected/pages/Controls/Samples/TButton/Home.page -text
demos/quickstart/protected/pages/Controls/Samples/TButton/Home.php -text
+demos/quickstart/protected/pages/Controls/Samples/TCaptcha/Home.page -text
+demos/quickstart/protected/pages/Controls/Samples/TCaptcha/Home.php -text
demos/quickstart/protected/pages/Controls/Samples/TCheckBox/Home.page -text
demos/quickstart/protected/pages/Controls/Samples/TCheckBox/Home.php -text
demos/quickstart/protected/pages/Controls/Samples/TCheckBoxList/Home.page -text
diff --git a/demos/quickstart/protected/pages/Controls/Captcha.page b/demos/quickstart/protected/pages/Controls/Captcha.page
new file mode 100644
index 00000000..244a3adc
--- /dev/null
+++ b/demos/quickstart/protected/pages/Controls/Captcha.page
@@ -0,0 +1,39 @@
+<com:TContent ID="body" >
+
+<h1>TCaptcha</h1>
+<com:DocLink ClassPath="System.Web.UI.WebControls.TCaptcha" />
+
+<p>
+<tt>TCaptcha</tt> displays a <a href="http://en.wikipedia.org/wiki/Captcha">CAPTCHA</a> that can be used to determine if the input is entered by a real user instead of some program. <tt>TCaptcha</tt> displays a token (a string consisting of alphanumeric characters) as an image and the user is expected to repeat the token in a text box. The token image is generated in a way such that it can be recognized by a human being, but not a program.
+</p>
+
+<p>
+To use <tt>TCaptcha</tt>, you must enable the PHP GD2 extension with TrueType font support. Unlike other CAPTCHA scripts, <tt>TCaptcha</tt> does not need session or cookie.
+</p>
+
+<p>
+The token generated by <tt>TCaptcha</tt> can be configured in several ways. To specify the length of characters in the token, set <tt>MinTokenLength</tt> and <tt>MaxTokenLength</tt>. To use case-insensitive token comparison and generate upper-case-only token, set <tt>CaseSensitive</tt> to false. More advanced users can try to set <tt>TokenAlphabet</tt> to specify which characters may appear in the generated tokens.
+</p>
+
+<p>
+To specify the appearance of the generated token image, set <tt>TokenImageTheme</tt> to be an integer between 0 and 31. You may try the following example to see how this value affects the generated token image. The size of the generated token image is determined by <tt>TokenFontSize</tt>. In particular, the image width is proportional to the font size. You may also set <tt>Width</tt> to scale the generated image to your desired size, but the scaled image may not look good.
+</p>
+
+<p>
+Upon postback, user input can be validated by calling the method <tt>TCaptcha.validate()</tt>. More easily, you can use a <tt>TCaptchaValidator</tt> to automate the validation work for you. The <tt>TCaptchaValidator</tt> has the additional benefit of being able to validate the user input on the client-side. By default, a generated token will remain unchanged during postbacks. A new token can be generated by calling <tt>TCaptcha.regenerateToken()</tt> manually.
+</p>
+
+<p>
+The following template shows a typical use of the <tt>TCaptcha</tt> control:
+</p>
+<com:TTextHighlighter Language="prado" CssClass="source">
+&lt;com:TCaptcha ID="Captcha" />
+&lt;com:TTextBox ID="Input" />
+&lt;com:TCaptchaValidator CaptchaControl="Captcha"
+ ControlToValidate="Input"
+ ErrorMessage="You are challenged!" />
+</com:TTextHighlighter>
+
+<com:RunBar PagePath="Controls.Samples.TCaptcha.Home" />
+
+<div class="last-modified">$Id$</div></com:TContent> \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/Controls/Samples/TCaptcha/Home.page b/demos/quickstart/protected/pages/Controls/Samples/TCaptcha/Home.page
new file mode 100644
index 00000000..f47583e9
--- /dev/null
+++ b/demos/quickstart/protected/pages/Controls/Samples/TCaptcha/Home.page
@@ -0,0 +1,32 @@
+<com:TContent ID="body">
+<h1>TCaptcha Samples</h1>
+
+<h2>Validating CAPTCHA</h2>
+<com:TCaptcha ID="Captcha" TokenImageTheme="5"/>
+<com:TTextBox ID="Input" />
+<com:TButton Text="Regenerate" OnClick="regenerateToken" CausesValidation="false" />
+<com:TButton Id="SubmitButton" Text="Submit" OnClick="buttonClicked" />
+<com:TCaptchaValidator CaptchaControl="Captcha" ControlToValidate="Input" Text="error" />
+
+<h2>Different Themes of TCaptcha</h2>
+
+<table border="1">
+<tr>
+<th>Theme</th><th>Image</th>
+</tr>
+<com:TRepeater ID="CaptchaList">
+ <prop:ItemTemplate>
+<tr>
+ <td>
+ <%# $this->Data %>
+ </td>
+ <td>
+ <com:TCaptcha TokenImageTheme="<%# $this->Data %>" MaxTokenLength="5"/>
+ </td>
+</tr>
+ </prop:ItemTemplate>
+</com:TRepeater>
+</table>
+
+<div class="last-modified">$Id$</div>
+</com:TContent> \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/Controls/Samples/TCaptcha/Home.php b/demos/quickstart/protected/pages/Controls/Samples/TCaptcha/Home.php
new file mode 100644
index 00000000..4d54ce87
--- /dev/null
+++ b/demos/quickstart/protected/pages/Controls/Samples/TCaptcha/Home.php
@@ -0,0 +1,27 @@
+<?php
+
+class Home extends TPage
+{
+ public function onInit($param)
+ {
+ if(!$this->IsPostBack)
+ {
+ $this->CaptchaList->DataSource=range(0,31);
+ $this->CaptchaList->dataBind();
+ }
+ }
+
+ public function regenerateToken($sender,$param)
+ {
+ $this->Captcha->regenerateToken();
+ $this->SubmitButton->Text="Submit";
+ }
+
+ public function buttonClicked($sender,$param)
+ {
+ if($this->IsValid)
+ $sender->Text="You passed!";
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/Controls/Standard.page b/demos/quickstart/protected/pages/Controls/Standard.page
index d481525c..7d961a84 100644
--- a/demos/quickstart/protected/pages/Controls/Standard.page
+++ b/demos/quickstart/protected/pages/Controls/Standard.page
@@ -8,6 +8,10 @@
</li>
<li>
+ <a href="?page=Controls.Captcha">TCaptcha</a> displays a CAPTCHA to keep spammers from signing up for certain accounts online.
+ </li>
+
+ <li>
<a href="?page=Controls.CheckBox">TCheckBox</a> represents a checkbox on a Web page. It can be used to collect two-state user input.
</li>
diff --git a/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page b/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page
index a5136d72..53b516cc 100644
--- a/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page
+++ b/demos/quickstart/protected/pages/GettingStarted/NewFeatures.page
@@ -10,7 +10,7 @@ This page summarizes the main new features that are introduced in each PRADO rel
<ul>
<li>Added a new control <a href="?page=Controls.TabPanel">TTabPanel</a> that displays tabbed views.</li>
<li>Added a new control <a href="?page=Controls.Keyboard">TKeyboard</a> that displays a virtual keyboard for text input.</li>
-<li>Added a new module TCacheHttpSession that stores session data using a cache module to improve the session performance.</li>
+<li>Added a new control <a href="?page=Controls.Captcha">TCaptcha</a> that displays a CAPTCHA to keep spammers from signing up for certain accounts online. A related validator <tt>TCaptchaValidator</tt> is also implemented.</li>
<li>Added Oracle DB support to Active Record</li>
</ul>
diff --git a/framework/Exceptions/messages/messages.txt b/framework/Exceptions/messages/messages.txt
index a60b8226..33a6f752 100644
--- a/framework/Exceptions/messages/messages.txt
+++ b/framework/Exceptions/messages/messages.txt
@@ -432,4 +432,14 @@ urlmapping_configfile_invalid = TUrlMapping.ConfigFile '{0}' must point to an
urlmappingpattern_serviceparameter_required = TUrlMappingPattern.ServiceParameter is required for pattern '{0}'.
keyboard_forcontrol_required = TKeyboard.ForControl cannot be empty.
-keyboard_forcontrol_invalid = TKeyboard.ForControl '{0}' is invalid. \ No newline at end of file
+keyboard_forcontrol_invalid = TKeyboard.ForControl '{0}' is invalid.
+
+captcha_tokenimagetheme_invalid = TCaptcha.TokenImageTheme must be an integer between {0} and {1}.
+captcha_tokenfontsize_invalid = TCaptcha.TokenFontSize must be an integer between {0} and {1}.
+captcha_mintokenlength_invalid = TCaptcha.MinTokenLength must be an integer between {0} and {1}.
+captcha_maxtokenlength_invalid = TCaptcha.MaxTokenLength must be an integer between {0} and {1}.
+captcha_tokenalphabet_invalid = TCaptcha.TokenAlphabet must be a string consisting of at least 2 characters.
+captcha_privatekey_unknown = TCaptcha.PrivateKey is unknown. Please make sure that your assets directory is writable by the Web server process.
+captcha_gd2_required = TCaptcha requires PHP GD2 extension.
+captcha_imagettftext_required = TCaptcha requires PHP GD2 extension with TrueType font support.
+captcha_imagepng_required = TCaptcha requires PHP GD2 extension with PNG image format support. \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TCaptcha.php b/framework/Web/UI/WebControls/TCaptcha.php
index 17e9ad34..bff04236 100644
--- a/framework/Web/UI/WebControls/TCaptcha.php
+++ b/framework/Web/UI/WebControls/TCaptcha.php
@@ -18,11 +18,18 @@ Prado::using('System.Web.UI.WebControls.TImage');
* TCaptcha displays a CAPTCHA (a token displayed as an image) that can be used
* to determine if the input is entered by a real user instead of some program.
*
+ * Unlike other CAPTCHA scripts, TCaptcha does not need session or cookie.
+ *
* The token (a string consisting of alphanumeric characters) displayed is automatically
* generated and can be configured in several ways. To specify the length of characters
* in the token, set {@link setMinTokenLength MinTokenLength} and {@link setMaxTokenLength MaxTokenLength}.
* To use case-insensitive comparison and generate upper-case-only token, set {@link setCaseSensitive CaseSensitive}
- * to false.
+ * to false. More advanced users can try to set {@link setTokenAlphabet TokenAlphabet}, which
+ * specifies what characters can appear in tokens.
+ *
+ * To specify the appearance of the generated token image, set {@link setTokenImageTheme TokenImageTheme}
+ * to be an integer between 0 and 31. And to adjust the generated image size, set {@link setTokenFontSize TokenFontSize}
+ * (you may also set {@link TWebControl::setWidth Width}, but the scaled image may not look good.)
*
* Upon postback, user input can be validated by calling {@link validate()}.
* The {@link TCaptchaValidator} control can also be used to do validation, which provides
@@ -30,6 +37,15 @@ Prado::using('System.Web.UI.WebControls.TImage');
* remain the same during multiple postbacks. A new one can be generated by calling
* {@link regenerateToken()} manually.
*
+ * The following template shows a typical use of TCaptcha control:
+ * <code>
+ * <com:TCaptcha ID="Captcha" />
+ * <com:TTextBox ID="Input" />
+ * <com:TCaptchaValidator CaptchaControl="Captcha"
+ * ControlToValidate="Input"
+ * ErrorMessage="You are challenged!" />
+ * </code>
+ *
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id$
* @package System.Web.UI.WebControls
@@ -41,6 +57,9 @@ class TCaptcha extends TImage
const MAX_TOKEN_LENGTH=40;
private $_privateKey;
+ /**
+ * Checks the requirements needed for using TCaptcha.
+ */
public function onInit($param)
{
parent::onInit($param);
@@ -48,6 +67,58 @@ class TCaptcha extends TImage
}
/**
+ * @return integer the theme of the token image. Defaults to 0.
+ */
+ public function getTokenImageTheme()
+ {
+ return $this->getViewState('TokenImageTheme',0);
+ }
+
+ /**
+ * Sets the theme of the token image.
+ * You may test each theme to find out the one you like the most.
+ * Below is the explanation of the theme value:
+ * It is treated as a 5-bit integer. Each bit toggles a specific feature of the image.
+ * Bit 0 (the least significant): whether the image is opaque (1) or transparent (0).
+ * Bit 1: whether we should add white noise to the image (1) or not (0).
+ * Bit 2: whether we should add a grid to the image (1) or not (0).
+ * Bit 3: whether we should add some scribbles to the image (1) or not (0).
+ * Bit 4: whether the image background should be morphed (1) or not (0).
+ * @param integer the theme of the token image. It must be an integer between 0 and 31.
+ */
+ public function setTokenImageTheme($value)
+ {
+ $value=TPropertyValue::ensureInteger($value);
+ if($value>=0 && $value<=31)
+ $this->setViewState('TokenImageTheme',$value,0);
+ else
+ throw new TConfigurationException('captcha_tokenimagetheme_invalid',0,31);
+ }
+
+ /**
+ * @return integer the font size used for displaying the token in an image. Defaults to 30.
+ */
+ public function getTokenFontSize()
+ {
+ return $this->getViewState('TokenFontSize',30);
+ }
+
+ /**
+ * Sets the font size used for displaying the token in an image.
+ * This property affects the generated token image size.
+ * The image width is proportional to this font size.
+ * @param integer the font size used for displaying the token in an image. It must be an integer between 20 and 100.
+ */
+ public function setTokenFontSize($value)
+ {
+ $value=TPropertyValue::ensureInteger($value);
+ if($value>=20 && $value<=100)
+ $this->setViewState('TokenFontSize',$value,30);
+ else
+ throw new TConfigurationException('captcha_tokenfontsize_invalid',20,100);
+ }
+
+ /**
* @return integer the minimum length of the token. Defaults to 5.
*/
public function getMinTokenLength()
@@ -104,11 +175,11 @@ class TCaptcha extends TImage
}
/**
- * @return string the characters that may appear in the token. Defaults to '234578adefhijmnrtABDEFGHJLMNQRT'.
+ * @return string the characters that may appear in the token. Defaults to '234578adefhijmnrtABDEFGHJLMNRT'.
*/
public function getTokenAlphabet()
{
- return $this->getViewState('TokenAlphabet','234578adefhijmnrtABDEFGHJLMNQRT');
+ return $this->getViewState('TokenAlphabet','234578adefhijmnrtABDEFGHJLMNRT');
}
/**
@@ -118,7 +189,7 @@ class TCaptcha extends TImage
{
if(strlen($value)<2)
throw new TConfigurationException('captcha_tokenalphabet_invalid');
- $this->setViewState('TokenAlphabet',$value,'234578adefhijmnrtABDEFGHJLMNQRT');
+ $this->setViewState('TokenAlphabet',$value,'234578adefhijmnrtABDEFGHJLMNRT');
}
/**
@@ -241,6 +312,8 @@ class TCaptcha extends TImage
$options['tokenLength']=strlen($token);
$options['caseSensitive']=$this->getCaseSensitive();
$options['alphabet']=$this->getTokenAlphabet();
+ $options['fontSize']=$this->getTokenFontSize();
+ $options['theme']=$this->getTokenImageTheme();
$str=serialize($options);
return base64_encode(md5($privateKey.$str).$str);
}
diff --git a/framework/Web/UI/WebControls/assets/captcha.php b/framework/Web/UI/WebControls/assets/captcha.php
index 3941eb44..2a4952a9 100644
--- a/framework/Web/UI/WebControls/assets/captcha.php
+++ b/framework/Web/UI/WebControls/assets/captcha.php
@@ -10,9 +10,17 @@
* @package System.Web.UI.WebControls.assets
*/
+define('THEME_OPAQUE_BACKGROUND',0x0001);
+define('THEME_NOISY_BACKGROUND',0x0002);
+define('THEME_HAS_GRID',0x0004);
+define('THEME_HAS_SCRIBBLE',0x0008);
+define('THEME_MORPH_BACKGROUND',0x0010);
+
require_once(dirname(__FILE__).'/captcha_key.php');
$token='error';
+$theme=0;
+
if(isset($_GET['options']))
{
$str=base64_decode($_GET['options']);
@@ -27,12 +35,14 @@ if(isset($_GET['options']))
$tokenLength=$options['tokenLength'];
$caseSensitive=$options['caseSensitive'];
$alphabet=$options['alphabet'];
+ $fontSize=$options['fontSize'];
+ $theme=$options['theme'];
$token=generateToken($publicKey,$privateKey,$alphabet,$tokenLength,$caseSensitive);
}
}
}
-displayToken($token);
+displayToken($token,$fontSize,$theme);
function generateToken($publicKey,$privateKey,$alphabet,$tokenLength,$caseSensitive)
{
@@ -40,10 +50,10 @@ function generateToken($publicKey,$privateKey,$alphabet,$tokenLength,$caseSensit
return $caseSensitive?$token:strtoupper($token);
}
-function hash2string($hex,$alphabet='')
+function hash2string($hex,$alphabet)
{
if(strlen($alphabet)<2)
- $alphabet='234578adefhijmnrtABDEFGHJLMNQRT';
+ $alphabet='234578adefhijmnrtABDEFGHJLMNRT';
$hexLength=strlen($hex);
$base=strlen($alphabet);
$result='';
@@ -59,47 +69,144 @@ function hash2string($hex,$alphabet='')
return $result;
}
-function displayToken($token)
+function displayToken($token,$fontSize,$theme)
{
+ if(($fontSize=(int)$fontSize)<22)
+ $fontSize=22;
+ if($fontSize>100)
+ $fontSize=100;
$length=strlen($token);
- $width=45*$length;
- $height=70;
+ $padding=10;
+ $fontWidth=$fontSize;
+ $fontHeight=floor($fontWidth*1.5);
+ $width=$fontWidth*$length+$padding*2;
+ $height=$fontHeight;
$image=imagecreatetruecolor($width,$height);
+
+ addBackground
+ (
+ $image, $width, $height,
+ $theme&THEME_OPAQUE_BACKGROUND,
+ $theme&THEME_NOISY_BACKGROUND,
+ $theme&THEME_HAS_GRID,
+ $theme&THEME_HAS_SCRIBBLE,
+ $theme&THEME_MORPH_BACKGROUND
+ );
+
$font=dirname(__FILE__).DIRECTORY_SEPARATOR.'verase.ttf';
- $vred=rand(0,100);
- $vgreen=rand(0,100);
- $vblue=rand(0,100);
+
+ if(function_exists('imagefilter'))
+ imagefilter($image,IMG_FILTER_GAUSSIAN_BLUR);
+
+ for($i=0;$i<$length;$i++)
+ {
+ $color=imagecolorallocate($image,rand(150,220),rand(150,220),rand(150,220));
+ imagettftext($image,rand($fontWidth-10,$fontWidth),rand(-30, 30),$padding+$i*$fontWidth,rand($fontHeight-15,$fontHeight-10),$color,$font,$token[$i]);
+ imagecolordeallocate($image,$color);
+ }
+
+ imagepng($image);
+ imagedestroy($image);
+}
+
+function addBackground($image,$width,$height,$opaque,$noisy,$hasGrid,$hasScribble,$morph)
+{
+ $background=imagecreatetruecolor($width*2,$height*2);
+ $white=imagecolorallocate($background,255,255,255);
+ imagefill($background,0,0,$white);
+
+ if($opaque)
+ imagefill($background,0,0,imagecolorallocate($background,100,100,100));
+
+ if($noisy)
+ addNoise($background,$width*2,$height*2);
+
+ if($hasGrid)
+ addGrid($background,$width*2,$height*2);
+
+ if($hasScribble)
+ addScribble($background,$width*2,$height*2);
+
+ if($morph)
+ morphImage($background,$width*2,$height*2);
+
+ imagecopy($image,$background,0,0,30,30,$width,$height);
+
+ if(!$opaque)
+ imagecolortransparent($image,$white);
+}
+
+function addNoise($image,$width,$height)
+{
for($x=0;$x<$width;++$x)
{
for($y=0;$y<$height;++$y)
{
- $vred+=rand(-2,2);
- $vgreen+=rand(-2,2);
- $vblue+=rand(-2,2);
- if($vred<0) $vred=0; if($vred>150) $vred=75;
- if($vgreen<0) $vgreen=0; if($vgreen>150) $vgreen=75;
- if($vblue<0) $vblue=0; if($vblue>150) $vblue=75;
- $col = imagecolorallocate($image, $vred, $vgreen, $vblue);
- imagesetpixel($image, $x, $y, $col);
- imagecolordeallocate($image, $col);
+ if(rand(0,100)<25)
+ {
+ $color=imagecolorallocate($image,rand(150,220),rand(150,220),rand(150,220));
+ imagesetpixel($image,$x,$y,$color);
+ imagecolordeallocate($image,$color);
+ }
}
}
+}
- imagefilter($image,IMG_FILTER_GAUSSIAN_BLUR);
- for($i=0;$i<$length;$i++)
+function addGrid($image,$width,$height)
+{
+ for($i=0;$i<$width;$i+=rand(15,25))
{
- $vred = rand(150, 240);
- $vgreen = rand(150, 240);
- $vblue = rand(150, 240);
- $col = imagecolorallocate($image, $vred, $vgreen, $vblue);
- $char = $token[$i];
- imagettftext($image, rand(40, 50), rand(-10, 20), 13 + (40 * $i), rand(50, imagesy($image) - 10), $col, $font, $char);
- imagecolordeallocate($image, $col);
- }
- imagefilter($image,IMG_FILTER_GAUSSIAN_BLUR);
+ imagesetthickness($image,rand(2,6));
+ $color=imagecolorallocate($image,rand(100,180),rand(100,180),rand(100,180));
+ imageline($image,$i+rand(-10,20),0,$i+rand(-10,20),$height,$color);
+ imagecolordeallocate($image,$color);
+ }
+ for($i=0;$i<$height;$i+=rand(15,25))
+ {
+ imagesetthickness($image,rand(2,6));
+ $color=imagecolorallocate($image,rand(100,180),rand(100,180),rand(100,180));
+ imageline($image,0,$i+rand(-10,20),$width,$i+rand(-10,20),$color);
+ imagecolordeallocate($image,$color);
+ }
+}
- imagepng($image);
- imagedestroy($image);
+function addScribble($image,$width,$height)
+{
+ for($i=0;$i<8;$i++)
+ {
+ $color=imagecolorallocate($image,rand(100,180),rand(100,180),rand(100,180));
+ $points=array();
+ for($j=1;$j<rand(5,10);$j++)
+ {
+ $points[]=rand(2*(20*($i+1)),2*(50*($i+1)));
+ $points[]=rand(30,$height+30);
+ }
+ imagesetthickness($image,rand(2,6));
+ imagepolygon($image,$points,intval(sizeof($points)/2),$color);
+ imagecolordeallocate($image,$color);
+ }
+}
+
+function morphImage($image,$width,$height)
+{
+ $tempImage=imagecreatetruecolor($width,$height);
+ $chunk=rand(1,5);
+ for($x=$y=0;$x<$width;$x+=$chunk)
+ {
+ $chunk=rand(1,5);
+ $y+=rand(-1,1);
+ if($y>=$height) $y=$height-5;
+ if($y<0) $y=5;
+ imagecopy($tempImage,$image,$x,0,$x,$y,$chunk,$height);
+ }
+ for($x=$y=0;$y<$height;$y+=$chunk)
+ {
+ $chunk=rand(1,5);
+ $x+=rand(-1,1);
+ if($x>=$width) $x=$width-5;
+ if($x<0) $x=5;
+ imagecopy($image,$tempImage,$x,$y,0,$y,$width,$chunk);
+ }
}
?> \ No newline at end of file