📜 ⬆️ ⬇️

Generating avatars with PHP, eyes



Like the authors of a recent topic , I faced the question of generating default avatars. He immediately remembered the "fractal" avatars.

The basic principle is to generate 1/4 images with primitives and duplicate them with a 90 ° rotation. I tried to make my own version:


Sortsy
<?php $w=150; $h=150; $cols=4; $im = imageCreate($w,$h); $del=1.5; $mw = $w/$del; $mh = $h/$del; $c = imageColorAllocate($im, 245, 245, 245); imagefilledrectangle($im, 0, 0, $w, $h, $c); $c = array(rand(0,200),rand(0,200),rand(0,200)); for($zz=0;$zz<5;$zz++) { $im = createPolgon($im, $w, $h, $mw, $mh,5, $c, 75); } header('Content-type: image/jpg'); imagepng($im); imagedestroy($im); function createPolgon($image, $width, $height, $mwidth, $mheight, $count, $color, $merge) { $img = imageCreate($width,$height); $c = imageColorAllocate($img, 245, 245, 245); imagefilledrectangle($img, 0, 0, $width, $height, $c); for($i=0;$i<$count;$i++) { $c = imageColorAllocate($image,$color[0],$color[1],$color[2]); $cnt=3; $values=array(rand(0,$mwidth), rand(0,$mheight),rand(0,$mwidth), rand(0,$mheight),rand(0,$mwidth), rand(0,$mheight)); imagefilledpolygon($image, $values, $cnt, $c); } $rotate = imagerotate($image, 90, 0); imagecopymerge($image, $rotate, 0, 0, 0, 0, $width, $height, 50); $rotate = imagerotate($image, 180, 0); imagecopymerge($image, $rotate, 0, 0, 0, 0, $width, $height, 50); imagecopymerge($img, $image, 0, 0, 0, 0, $width, $height, $merge); return $img; } 



Like any designer, "played with colors and shapes," but it was not that. Then the idea was born to make randomly generated faces. I even thought about en $% e, but thought it over in time. The plans were only the generation of persons in the style of "cartoon" - with multi-colored eyes, hair and caricature features, and after thinking about accessories - glasses, blush, freckles, etc ...
In a hurry sketched his faces,


and set to work on various parts of the face. Let's start with the eyes.
The basic shape for the eye is a drop.
')


In general, this form is basic for many parts of the avatar - nostrils, lips, etc. To get it is quite simple - from a parabola . More precisely - out of four:



Source code for half fixed size parabola
 /* $width, $height - ,   $quality -   */ $color = imageColorAllocate($image,45,45,45) $points = array(); for($x=0; $x<=$width/2; $x+=$quality) { $y=($x*$x) / (($width)*($width)) * $height; array_push($points, $x, $y); } imagefilledpolygon($image, $points, count($points)/2, $color); 


And imagefilledpolygon fills the polygon with the selected color in the contour, given by an array of points in the Cartesian coordinate system. Read more about drawing with PHP tools here .
Make a thin outline of the eye in black. imagepolygon - just right - a polygon around a non-fill.

Stroke, shadow from eyelid, shade, white.


Pupil and glare paint using imagefilledellipse .

Pupil, glare.


Eye customization is done using rand

raw source
 <?php /*   .   ,   .   -  .  -    . */ $Width=500; $Height=300; $img = imageCreate($Width,$Height); $r = rand(5,200);$g = rand(5,200);$b = rand(5,200); $c = imageColorAllocate($img, 255,255,255); imagefilledrectangle($img, 0, 0, $Width, $Height, $c); //------------------- ------------------------// $w = rand(100,150); $h = rand(100,100); $zsize=rand(20,50); $max = rand(2,7)/10; $max2= 0.5; $zxr = rand(-$w/5,$w/5); $zyr = rand(-$h/5,$h/5); $zform = rand(3,8)/10; $mejg = rand($w/2,$w); $zc = imageColorAllocate($img,rand(5,150),rand(5,150),rand(5,150)); $ec = imageColorAllocate($img,$r,$g,$b); $ebc = imageColorAllocate($img,rand(235,255),rand(235,255),rand(230,255)); $eform = rand(90,100)/100; $eform2 = rand(70,100)/100; $rznglaz = rand(80,120)/100; $rznglaz2 = rand(80,120)/100; $smeshx = (500 - ($w*2+$mejg))/2; DrawEye($img, $smeshx+0,0, $w*$rznglaz,$h ,$ec, $ebc, $eform, $eform2, $zxr, $zyr, $zc, $max, $max2, $zform, $zsize); if(rand(0,5)==0) $zc = imageColorAllocate($img,rand(5,150),rand(5,150),rand(5,150)); DrawEye($img, $smeshx+$w + $mejg, 0, $w*$rznglaz2, $h, $ec, $ebc, $eform, $eform2, $zxr, $zyr, $zc, 1-$max, $max2, $zform, $zsize); //imageellipse ( $img , 100 , 100 ,100 , 100 , imageColorAllocate($img,45,45,45) ); //imagefilledellipse ( $img , 200 , 200 ,100 , 100 , imageColorAllocate($img,45,45,45) ); //-----------------   -----------------------// header('Content-type: image/png'); imagepng($img); imagedestroy($img); //-------------------------------------------------------// function DrawEye($image, $xx, $yy, $w, $h, $ec, $ebc, $eform, $eform2, $zxr,$zyr, $zc, $max, $max2, $zform, $zsize) { /* if($w<$h) $zsize = $w/3; else $zsize = $h/3; */ DrawEyePoligon($image,$xx-5,95-5,$w+10,$h+10, imageColorAllocate($image,5,5,5), 1, $max, $max2, 0); DrawEyePoligon($image,$xx,95,$w,$h, imageColorAllocate($image,5,5,5), 1, $max, $max2, 1); DrawEyePoligon($image,$xx,100,$w,$h*$eform, $ec, 1, $max, $max2, 1); DrawEyePoligon($image,$xx+10,100+$zform*10,$w-20,$h*$eform2, $ebc, 1, $max2,$max2, 1); DrawEyePoligon($image,$xx+10,100+$zform*10,$w-20,$h*$eform2, $ebc, 1, $max2,$max2, 1); imagefilledellipse ( $image, $xx+$w/2+$zxr,140+$zyr, $zsize, $zsize, $zc); imagefilledellipse ( $image, $xx+$w/2+$zxr,140+$zyr, $zsize * $zform, $zsize*(1-$zform), imageColorAllocate($image,5,5,5)); imagefilledellipse ( $image, $xx+$w/2+$zxr+10,140+$zyr-10, $zsize * 0.5, $zsize*0.5, imageColorAllocate($image,255,255,255)); } //-------------------------------------------------------// function DrawEyePoligon($image, $xx, $yy, $width, $height, $color, $quality, $max, $max2, $fill) { $height/=2; if($quality>$width/2) $quality=$width/2; $points = array(); for($i=0; $i<=$width; $i+=$quality) { $x = $i-$width; $y=($x*$x) / (($width)*($width)) * $height; array_push($points, $i*$max, $y); } for($i=0; $i<=$width; $i+=$quality) { $x = $i; $y=($x*$x) / (($width)*($width)) * $height; //$y=(($width*$width)-($x*$x)) / (($width)*($width)) * $height; array_push($points, $i*(1-$max)+($width*$max), $y); } for($i=0; $i<=$width; $i+=$quality) { $x = $i-$width; $y=-($x*$x) / (($width)*($width)) * $height; array_push($points, $i*$max2, 2*$height+$y); } for($i=0; $i<=$width; $i+=$quality) { $x = $i; $y=-($x*$x) / (($width)*($width)) * $height; //$y=(($width*$width)-($x*$x)) / (($width)*($width)) * $height; array_push($points, $i*(1-$max2)+($width*$max2), 2*$height+$y); } DrawPoligon($image, $xx, $yy, $points, $color, $fill); } //-------------------------------------------------------// function DrawPoligon($image, $x, $y, $points, $color, $fill) { for($i=0; $i<count($points); $i+=2) { $points[$i]+=$x; $points[$i+1]+=$y; } if($fill) imagefilledpolygon($image, $points, count($points)/2, $color); else imagepolygon($image, $points, count($points)/2, $color); } 



The remaining parts of the face (except hair and accessories) are drawn in the same way. It turns out beautifully, but there is a big and fat minus - it is very expensive even if optimized. And overlaying each other ready-made patterns may be better, but boring and monotonous. We bow back, happy and thanks for the fish.

Source: https://habr.com/ru/post/164243/


All Articles