Related
I have done a lot of searching for this and have found lots of help to generate a maze, but I have a very specific requirement and all the loops Iv tried have failed horribly.
I created an editor where I could draw what I need, but a generator would help a great deal and this has failed.
Requirement:
Given a square grid of DIV elements (no smaller than 10x10 and no larger than 60x60) I need a joined path through and around the grid that will not touch itself at any point except at start/finish.
There must always be at least one blank square between all path squares (any number of blanks is fine so long as the path never comes into contact with itself).
There can be no dead ends and no loops (Where the path would cross itself).
This is kind of like a reverse maze - I do not need to fill the entire grid, in fact I have no problem with lots of space around the path. It might be easier to think of this along similar lines to a Monopoly board game where the path around the board wanders about instead of going around the edges. I'm actually stuck for an adequate description, hence calling it a reverse maze.
Things I tried:
Lots and lots of overly complex loops. Iv not really come very close and the issue is also one of performance.
Lots and lots of code designed to generate a maze. Some of these have been very good indeed, but they all generate a typical maze, which is not what I need at all really, and adapting the code has proven trickier than writing an insane set of loops within loops.
Any ideas would be helpful. Thanks.
Update Code
Okay, I have translated KIKO's PHP code into Javascript but somewhere along the line I have made a simple error that I cannot track down: The code works and generates a table of the correct dimensions and generates a path through it.
However, in the function "isWithinGrid" I have to subtract 1 from the width and height of the table or the entire thing will fail, and, if I do this, the code will work and created a path through the table minus one cell which will be incorrectly colored although clearly a part of the path.
Note that sometimes the path will be broken or touching itself. I have little doubt that some small problem is causing all of this, but currently this is the best I have come up with and any further help would be much appreciated.
class Grid{
constructor(width,height){
this.width = width;
this.height = height;
this.cells = [];
for(var x=0; x < this.width; x++){
var tmparray = [];
for(var y=0; y < this.height; y++){
tmparray.push(false);
}
this.cells.push(tmparray);
}
}
isWithinGrid(x,y){
return (x >= 0) && (x <= this.width-1) && (y >= 0) && (y <= this.height-1);
}
isWithinPath(x,y){
return this.isWithinGrid(x,y) && this.cells[x][y];
}
setCellInPath(x,y,boolean){
this.cells[x][y] = boolean;
return this;
}
drawHorizontalLine(x1,x2,y){
for(var x=x1; x < x2; x++){
this.setCellInPath(x,y,true);
}
return this;
}
drawVerticalLine(x,y1,y2){
for(var y=y1; y < y2; y++){
this.setCellInPath(x,y,true);
}
return this;
}
drawSquare(){
var left = Math.round(this.width/5);
var right = Math.round(4*this.width/5);
var top = Math.round(this.height/5);
var bottom = Math.round(4*this.height/5);
this.drawHorizontalLine(left,right,top)
.drawHorizontalLine(left,right,bottom)
.drawVerticalLine(left,top,bottom)
.drawVerticalLine(right,top,bottom);
return this;
}
moveCell(x,y,dx,dy){
this.setCellInPath(x,y,false);
this.setCellInPath(x+dx,y+dy,true);
}
canMoveCell(x,y,dx,dy){
return this.isWithinPath(x,y) &&
this.isWithinGrid(x+dx,y+dy) &&
!this.isWithinPath(x+dx,y+dy) &&
!this.isWithinPath(x+2*dx,y+2*dy) &&
!this.isWithinPath(x+dy+dx,y+dx+dy)
!this.isWithinPath(x-dy+dx,y-dx+dy);
}
tryToDistortOnce(x,y,dx,dy){
if (!this.canMoveCell(x,y,dx,dy)) return false;
if (!this.canMoveCell(x+dy,y+dx,dx,dy)) return false;
if (!this.canMoveCell(x-dy,y-dx,dx,dy)) return false;
this.moveCell(x,y,dx,dy);
this.setCellInPath(x+dy+dx,y+dx+dy,true);
this.setCellInPath(x-dy+dx,y-dx+dy,true);
return true;
}
distortOnce(){
var x=0, y=0, dx=0, dy=0;
do {
x = Math.floor(Math.random() * this.width) + 1;
y = Math.floor(Math.random() * this.height) + 1;
} while (!this.isWithinPath(x,y));
switch (Math.floor(Math.random() * 4) + 1){
case 1: dx = -1; dy = 0; break;
case 2: dx = +1; dy = 0; break;
case 3: dx = 0; dy = +1; break;
case 4: dx = 0; dy = -1; break;
}
if (this.tryToDistortOnce(x,y,dx,dy)){
do {
x += dx;
y += dy;
} while (this.tryToDistortOnce(x,y,dx,dy));
return true;
}
return false;
}
distortPath(numberOfDistortions = 10){
for(var counter=1; counter < numberOfDistortions; counter++){
var tries = 0;
while (!this.distortOnce() && (tries < this.width+this.height)){ tries++; }
}
return this;
}
renderGrid(){
var str = '<table class="TSTTAB">';
for(var y=0; y < this.width; y++){
for(var x=0; x < this.height; x++){
str += '<td'+(this.cells[y][x] ? ' class="path">' : '>');
}
str += '</tr>';
}
str += '</table>';
document.getElementById('cont').innerHTML =str;
return this;
}
}
var Testgrid = new Grid(20,20);
Testgrid.drawSquare().distortPath(10).renderGrid();
.TSTTAB{background-color:#7F7F7F;border-collapse:collapse;}
.TSTTAB td{ width:20px; height: 20px; border: 1px solid #000;background-color: #E5E5E5; }
.TSTTAB td.path { background-color: #44F; }
<div id='cont'></div>
Well, I've given it a try. One hour of work seems more than enough for a simple question. It is, of course, far from perfect, but it illustrates what I was talking about. It generates solutions like this:
The complete code is:
<?php
// error reporting
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// configuration
const SIZE_X = 20;
const SIZE_Y = 20;
const COMPLEXITY = 20;
// grid class
class Grid
{
public function __construct($width,$height)
{
// remember
$this->width = $width;
$this->height = $height;
// initiate grid
foreach (range(1,$width) as $x) {
foreach (range(1,$height) as $y) {
$this->cells[$x][$y] = FALSE; // false means: not in path
}
}
}
public function isWithinGrid($x,$y)
// testb whether (x,y) is within the grid
{
return ($x >= 1) && ($x <= $this->width) &&
($y >= 1) && ($y <= $this->height);
}
public function isWithinPath($x,$y)
// is a cell part of the path?
{
return $this->isWithinGrid($x,$y) && $this->cells[$x][$y];
}
public function setCellInPath($x,$y,$boolean)
// remember whether a cell is part of the path or not
{
$this->cells[$x][$y] = $boolean;
return $this;
}
public function drawHorizontalLine($x1,$x2,$y)
// simple horizontal line
{
foreach (range($x1,$x2) as $x) $this->setCellInPath($x,$y,TRUE);
return $this;
}
public function drawVerticalLine($x,$y1,$y2)
// simple vertical line
{
foreach (range($y1,$y2) as $y) $this->setCellInPath($x,$y,TRUE);
return $this;
}
public function drawSquare()
// simple square
{
$left = round($this->width/5);
$right = round(4*$this->width/5);
$top = round($this->height/5);
$bottom = round(4*$this->height/5);
$this->drawHorizontalLine($left,$right,$top)
->drawHorizontalLine($left,$right,$bottom)
->drawVerticalLine($left,$top,$bottom)
->drawVerticalLine($right,$top,$bottom);
return $this;
}
private function moveCell($x,$y,$dx,$dy)
// move a cell
{
$this->setCellInPath($x,$y,FALSE);
$this->setCellInPath($x+$dx,$y+$dy,TRUE);
}
private function canMoveCell($x,$y,$dx,$dy)
// answers the question whether or not we can move (x,y) by (dx,dy)
{
return $this->isWithinPath($x,$y) && // must be part of path
$this->isWithinGrid($x+$dx,$y+$dy) && // stay within grid
!$this->isWithinPath($x+$dx,$y+$dy) && // but not on the path
!$this->isWithinPath($x+2*$dx,$y+2*$dy) && // and don't touch path
!$this->isWithinPath($x+$dy+$dx,$y+$dx+$dy) && // and don't touch path
!$this->isWithinPath($x-$dy+$dx,$y-$dx+$dy); // and don't touch path
}
private function tryToDistortOnce($x,$y,$dx,$dy)
{
// this one should be able to move
if (!$this->canMoveCell($x,$y,$dx,$dy)) return FALSE;
// but also its neighbours must be able to move
if (!$this->canMoveCell($x+$dy,$y+$dx,$dx,$dy)) return FALSE;
if (!$this->canMoveCell($x-$dy,$y-$dx,$dx,$dy)) return FALSE;
// move the target cell by displacement
$this->moveCell($x,$y,$dx,$dy);
// move neighbours by adding two cells
$this->setCellInPath($x+$dy+$dx,$y+$dx+$dy,TRUE);
$this->setCellInPath($x-$dy+$dx,$y-$dx+$dy,TRUE);
return TRUE; // success!
}
private function distortOnce()
// distort a random cell, returns success or failure
{
// find a random cell in path
do {
$x = rand(1,$this->width);
$y = rand(1,$this->height);
} while (!$this->isWithinPath($x,$y));
// choose one of four directions to move in
switch (rand(1,4))
{
case 1: $dx = -1; $dy = 0; break;
case 2: $dx = +1; $dy = 0; break;
case 3: $dx = 0; $dy = +1; break;
case 4: $dx = 0; $dy = -1; break;
}
// try to do it
if ($this->tryToDistortOnce($x,$y,$dx,$dy))
{
// more moves
do {
$x += $dx;
$y += $dy;
} while ($this->tryToDistortOnce($x,$y,$dx,$dy));
return TRUE; // it was a success!
}
return FALSE; // we failed
}
public function distortPath($numberOfDistortions = 10)
// distort up to a certain amount of times
{
// find a random cell that is part of the path to distort
for ($counter = 1; $counter <= $numberOfDistortions; $counter++) {
// we try that a limited number of times, depending on the grid size
$tries = 0;
while (!$this->distortOnce() &&
($tries < $this->width+$this->height)) { $tries++; }
}
return $this;
}
public function renderGrid()
// render grid
{
echo '<!DOCTYPE HTML><html><head><style>'.
' td { width:20px; height: 20px; border: 1px solid #000; }'.
' .path { background-color: #44F; }'.
'</style></head><body><table>';
foreach (range(1,SIZE_Y) as $y) {
echo '<tr>';
foreach (range(1,SIZE_X) as $x) {
echo '<td'.($this->cells[$x][$y] ? ' class="path">' : '>');
}
echo '</tr>';
}
echo '</body></html></table>';
return $this;
}
}
// create grid
$grid = new Grid(SIZE_X,SIZE_Y);
// start with a square, distort and then render
$grid->drawSquare()
->distortPath(COMPLEXITY)
->renderGrid();
There are lots of things you can do to improve on this.... have fun!
On my server this code takes between 2 and 5 milliseconds to execute. Mileage may vary...
I'm trying to develop an algorithm to create a symfony template service.
I want to check if a template exists in a subset of paths, ordered.
Given an array of parameter like this (already ordered like I want):
$params = ['O', 'U', 'W', 'P']
How can I output this array?
$urls = [
'O/U/W/P/template',
'O/U/W/template',
'O/U/P/template',
'O/U/template',
'O/W/P/template',
'O/W/template',
'O/P/template',
'O/template',
'U/W/P/template',
'U/W/template',
'U/P/template',
'U/template',
'W/P/template',
'W/template',
'P/template',
'template'
];
I can perform for a little list of parameters (like everyone can do it I suppose) with a code like this :
private function getPaths($template, $params)
{
$urls = [];
$alreadyPerform = [];
$paramsCounter = count($params);
for ($i = 0; $i < $paramsCounter; $i++) {
for ($j = 0; $j < $paramsCounter; $j++) {
if ($i !== $j && !in_array($params[$j], $alreadyPerform, true)) {
$urls[] = sprintf(
'/%s/%s/%s.html.twig', $params[$i], $params[$j], $template
);
}
}
$alreadyPerform[] = $params[$i];
$urls[] = sprintf('/%s/%s.html.twig', $params[$i], $template);
}
$urls[] = sprintf('%s.html.twig', $template);
return $urls;
}
This function work like I wanted until today (max 3 parameters), but I want to add one parameters today, maybe more after.
Thank you very much for your help !
Cheers.
Using recursion, you can do the following:
/**
* #param array $elements
* #param array $extra
*
* #return Generator
*/
function gen(array $elements, array $extra = []): \Generator {
foreach ($elements as $i => $head) {
foreach (gen(array_slice($elements, $i + 1), $extra) as $tail) {
yield array_merge([$head], $tail);
}
}
yield $extra;
}
demo: https://3v4l.org/gJB8q
Or without recursion:
/**
* #param array $elements
*
* #return Generator
*/
function gen2(array $elements): \Generator {
for ($num = count($elements), $i = pow(2, $num) - 1; $i >= 1; $i -= 2) {
$r = [];
for ($j = 0; $j < $num; $j += 1) {
if ($i & (1 << ($num - $j - 1))) {
$r[] = $elements[$j];
}
}
yield $r;
}
}
demo: https://3v4l.org/grKXo
Consider using the following package:
https://github.com/drupol/phpermutations
Just a very basic example of what it can do:
$permutations = new \drupol\phpermutations\Generators\Permutations(['A', 'B', 'C'], 2);
foreach ($permutations->generator() as $permutation) {
echo implode('/', $permutation);
echo "\n";
}
A/B
B/A
A/C
C/A
B/C
C/B
I have this problem with GD image processing in Opencart that creates real bad blurry images after resize. Nothing I have tried so far has helped.
Below is the code for the image.php
<?php
class Image {
private $file;
private $image;
private $info;
public function __construct($file) {
if (file_exists($file)) {
$this->file = $file;
$info = getimagesize($file);
$this->info = array(
'width' => $info[0],
'height' => $info[1],
'bits' => $info['bits'],
'mime' => $info['mime']
);
$this->image = $this->create($file);
} else {
exit('Error: Could not load image ' . $file . '!');
}
}
private function create($image) {
$mime = $this->info['mime'];
if ($mime == 'image/gif') {
return imagecreatefromgif($image);
} elseif ($mime == 'image/png') {
return imagecreatefrompng($image);
} elseif ($mime == 'image/jpeg') {
return imagecreatefromjpeg($image);
}
}
public function save($file, $quality = 100) {
$info = pathinfo($file);
$extension = strtolower($info['extension']);
if (is_resource($this->image)) {
if ($extension == 'jpeg' || $extension == 'jpg') {
imagejpeg($this->image, $file, $quality);
} elseif($extension == 'png') {
imagepng($this->image, $file);
} elseif($extension == 'gif') {
imagegif($this->image, $file);
}
imagedestroy($this->image);
}
}
/**
*
* #param width
* #param height
* #param default char [default, w, h]
* default = scale with white space,
* w = fill according to width,
* h = fill according to height
*
*/
public function resize($width = 0, $height = 0, $default = '') {
if (!$this->info['width'] || !$this->info['height']) {
return;
}
$xpos = 0;
$ypos = 0;
$scale = 1;
$scale_w = $width / $this->info['width'];
$scale_h = $height / $this->info['height'];
if ($default == 'w') {
$scale = $scale_w;
} elseif ($default == 'h'){
$scale = $scale_h;
} else {
$scale = min($scale_w, $scale_h);
}
if ($scale == 1 && $scale_h == $scale_w && $this->info['mime'] != 'image/png')
{
return;
}
$new_width = (int)($this->info['width'] * $scale);
$new_height = (int)($this->info['height'] * $scale);
$xpos = (int)(($width - $new_width) / 2);
$ypos = (int)(($height - $new_height) / 2);
$image_old = $this->image;
$this->image = imagecreatetruecolor($width, $height);
if (isset($this->info['mime']) && $this->info['mime'] == 'image/png') {
imagealphablending($this->image, false);
imagesavealpha($this->image, true);
$background = imagecolorallocatealpha($this->image, 255, 255, 255, 127);
imagecolortransparent($this->image, $background);
} else {
$background = imagecolorallocate($this->image, 255, 255, 255);
}
imagefilledrectangle($this->image, 0, 0, $width, $height, $background);
imagecopyresampled($this->image, $image_old, $xpos, $ypos, 0, 0, $new_width,
$new_height, $this->info['width'], $this->info['height']);
imagedestroy($image_old);
$this->info['width'] = $width;
$this->info['height'] = $height;
}
public function watermark($file, $position = 'bottomright') {
$watermark = $this->create($file);
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);
switch($position) {
case 'topleft':
$watermark_pos_x = 0;
$watermark_pos_y = 0;
break;
case 'topright':
$watermark_pos_x = $this->info['width'] - $watermark_width;
$watermark_pos_y = 0;
break;
case 'bottomleft':
$watermark_pos_x = 0;
$watermark_pos_y = $this->info['height'] - $watermark_height;
break;
case 'bottomright':
$watermark_pos_x = $this->info['width'] - $watermark_width;
$watermark_pos_y = $this->info['height'] - $watermark_height;
break;
}
imagecopy($this->image, $watermark,
$watermark_pos_x, $watermark_pos_y, 0, 0, 120, 40);
imagedestroy($watermark);
}
public function crop($top_x, $top_y, $bottom_x, $bottom_y) {
$image_old = $this->image;
$this->image = imagecreatetruecolor($bottom_x - $top_x, $bottom_y - $top_y);
imagecopy($this->image, $image_old, 0, 0, $top_x, $top_y,
$this->info['width'], $this->info['height']);
imagedestroy($image_old);
$this->info['width'] = $bottom_x - $top_x;
$this->info['height'] = $bottom_y - $top_y;
}
public function rotate($degree, $color = 'FFFFFF') {
$rgb = $this->html2rgb($color);
$this->image = imagerotate($this->image, $degree,
imagecolorallocate($this->image, $rgb[0], $rgb[1], $rgb[2]));
$this->info['width'] = imagesx($this->image);
$this->info['height'] = imagesy($this->image);
}
private function filter($filter) {
imagefilter($this->image, $filter);
}
private function text($text, $x = 0, $y = 0, $size = 5, $color = '000000') {
$rgb = $this->html2rgb($color);
imagestring($this->image, $size, $x, $y, $text,
imagecolorallocate($this->image, $rgb[0], $rgb[1], $rgb[2]));
}
private function merge($file, $x = 0, $y = 0, $opacity = 100) {
$merge = $this->create($file);
$merge_width = imagesx($image);
$merge_height = imagesy($image);
imagecopymerge($this->image, $merge, $x, $y, 0, 0, $merge_width,
$merge_height, $opacity);
}
private function html2rgb($color) {
if ($color[0] == '#') {
$color = substr($color, 1);
}
if (strlen($color) == 6) {
list($r, $g, $b) = array($color[0] . $color[1], $color[2] . $color[3],
$color[4] . $color[5]);
} elseif (strlen($color) == 3) {
list($r, $g, $b) = array($color[0] . $color[0], $color[1] . $color[1],
$color[2] . $color[2]);
} else {
return false;
}
$r = hexdec($r);
$g = hexdec($g);
$b = hexdec($b);
return array($r, $g, $b);
}
}
?>
As you can see the quality is already set to 100 , so that doesn't help.
I have tried replacing resize with resample - but that produced no visible result.
However I have found this suggestion (code below) to sharpen images, unfortunately I am not sure how and where to use it. Especially since original code processed multiple image types. Please help to put this in the right place.
{
$matrix = array(
array(-1, -1, -1),
array(-1, 16, -1),
array(-1, -1, -1),
);
$divisor = array_sum(array_map('array_sum', $matrix));
$offset = 0;
imageconvolution($image, $matrix, $divisor, $offset);
return $image;
}
Also, if you have other suggestions to improve this code, help is greatly appreciated! I think that goes for the whole Opencart community, as this has been discussed many time but no working solution posted as of yet.
The quality parameter will only be applicable to .jpeg images.
To sharpen the images you could apply the imageconvolution() code within the resize() function.
public function resize($width = 0, $height = 0, $default = '') {
if (!$this->info['width'] || !$this->info['height']) {
return;
}
$xpos = 0;
$ypos = 0;
$scale = 1;
$scale_w = $width / $this->info['width'];
$scale_h = $height / $this->info['height'];
if ($default == 'w') {
$scale = $scale_w;
} elseif ($default == 'h') {
$scale = $scale_h;
} else {
$scale = min($scale_w, $scale_h);
}
if ($scale == 1 && $scale_h == $scale_w && $this->info['mime'] != 'image/png') {
return;
}
$new_width = (int)($this->info['width'] * $scale);
$new_height = (int)($this->info['height'] * $scale);
$xpos = (int)(($width - $new_width) / 2);
$ypos = (int)(($height - $new_height) / 2);
$image_old = $this->image;
$this->image = imagecreatetruecolor($width, $height);
if (isset($this->info['mime']) && $this->info['mime'] == 'image/png') {
imagealphablending($this->image, false);
imagesavealpha($this->image, true);
$background = imagecolorallocatealpha($this->image, 255, 255, 255, 127);
imagecolortransparent($this->image, $background);
} else {
$background = imagecolorallocate($this->image, 255, 255, 255);
}
imagefilledrectangle($this->image, 0, 0, $width, $height, $background);
imagecopyresampled($this->image, $image_old, $xpos, $ypos, 0, 0, $new_width, $new_height, $this->info['width'], $this->info['height']);
//Image Sharpening Code
$matrix = array(
array(0.0, -1.0, 0.0),
array(-1.0, 5.0, -1.0),
array(0.0, -1.0, 0.0)
);
$divisor = array_sum(array_map('array_sum', $matrix));
$offset = 0;
imageconvolution($this->image, $matrix, $divisor, $offset);
// End Image Sharpening Code
imagedestroy($image_old);
$this->info['width'] = $width;
$this->info['height'] = $height;
}
References:
sharpen image quality with PHP gd library
http://adamhopkinson.co.uk/blog/2010/08/26/sharpen-an-image-using-php-and-gd/
I'm using FPDF with PHP to add an image to a PDF and I want to put automatically the size of the image I find this function
function fctaffichimage($img_Src, $W_max, $H_max) {
if (file_exists($img_Src)) {
$img_size = getimagesize($img_Src);
$W_Src = $img_size[0]; // largeur source
$H_Src = $img_size[1]; // hauteur source
if(!$W_max) { $W_max = 0; }
if(!$H_max) { $H_max = 0; }
$W_test = round($W_Src * ($H_max / $H_Src));
$H_test = round($H_Src * ($W_max / $W_Src));
if($W_Src<$W_max && $H_Src<$H_max) {
$W = $W_Src;
$H = $H_Src;
} elseif($W_max==0 && $H_max==0) {
$W = $W_Src;
$H = $H_Src;
} elseif($W_max==0) {
$W = $W_test;
$H = $H_max;
} elseif($H_max==0) {
$W = $W_max;
$H = $H_test;
}
elseif($H_test > $H_max) {
$W = $W_test;
$H = $H_max;
} else {
$W = $W_max;
$H = $H_test;
}
}
}
but when i do
// requĂȘte
$tab1 = $_GET['tab1'];
$ID = $_GET['ID'];
$table = $_GET['table'];
$ree = "SELECT title,title2 FROM $tab1 WHERE $table = $ID ORDER BY 1";
$sql2 = mysql_query($ree);
// on affiche les deux images avec la fontion fctaffichimage
while ($roww = mysql_fetch_assoc($sql2))
{
$nomm = $roww["title"];
$url = "/var/www/images/".$nomm ;
fctaffichimage($url,100,100 );
$pdf->Cell(40,6,'',0,0,'C',$pdf->Image($img_Src,85,55));
}
it didn't work
I try to change the position of $url = "/var/www/images/".$nomm ;
fctaffichimage($url,100,100 ); but it didn't work too.
I see something I hope to help you. Put at the bottom of the function fctaffichimage the next code:
$img1 = imagecreatefrompng($img_Src);
$img2 = imagecreatetruecolor($W, $H);
imagecopyresampled($img2, $img1, 0, 0, 0, 0, $W, $H, $W_Src, $W_Src);
imagepng($img2, $img_Src);
Here I put a PNG image, but you can generalize it, depends of you need. It's running in my enviroment with PHP 5.3 (but there's a new imagescale function in PHP 5.5).
I'm developing a email sending form. It has a captcha security image. When ever I refresh the image to load new captcha it always stores the previous session value. It never stores the correct one.
But in my localhost it works fine. Thank you very much.
class CaptchaSecurityImages {
var $font = 'monofont.ttf';
function generateCode($characters) {
/* list all possible characters, similar looking characters and vowels have been removed */
$possible = '23456789bcdfghjkmnpqrstvwxyz';
$code = '';
$i = 0;
while ($i < $characters) {
$code .= substr($possible, mt_rand(0, strlen($possible)-1), 1);
$i++;
}
$_SESSION['securitycode'] = $code;
return $code;
}
function CaptchaSecurityImages($width='120',$height='40',$characters='6') {
$code = $this->generateCode($characters);
/* font size will be 75% of the image height */
$_SESSION['securitycode'] = $code;
$font_size = $height * 0.75;
$image = #imagecreate($width, $height) or die('Cannot initialize new GD image stream');
/* set the colours */
$background_color = imagecolorallocate($image, 255, 255, 255);
$text_color = imagecolorallocate($image, 20, 40, 100);
$noise_color = imagecolorallocate($image, 100, 120, 180);
/* generate random dots in background */
for( $i=0; $i<($width*$height)/3; $i++ ) {
imagefilledellipse($image, mt_rand(0,$width), mt_rand(0,$height), 1, 1, $noise_color);
}
/* generate random lines in background */
for( $i=0; $i<($width*$height)/150; $i++ ) {
imageline($image, mt_rand(0,$width), mt_rand(0,$height), mt_rand(0,$width), mt_rand(0,$height), $noise_color);
}
/* create textbox and add text */
$textbox = imagettfbbox($font_size, 0, $this->font, $code) or die('Error in imagettfbbox function');
$x = ($width - $textbox[4])/2;
$y = ($height - $textbox[5])/2;
imagettftext($image, $font_size, 0, $x, $y, $text_color, $this->font , $code) or die('Error in imagettftext function');
/* output captcha image to browser */
header('Content-Type: image/jpeg');
imagejpeg($image);
imagedestroy($image);
}
}
This is the class I'm using to generate captcha.