Как и перед авторами недавнего топика, передо мной возник вопрос генерации дефолтных аватаров. Тут же вспомнил о «фрактальных» аватарах.
Основной принцип — генерируем примитивами 1/4 изображения и дублируем с поворотом на 90°. Пробовал сделать свой вариант:
Как и любой дизайнер, «поиграл цветами и формами», но все было не то. Тогда и родилась идея сделать случайно генерируемые лица. Подумывал даже об ан$%е, но вовремя отдумал. В планах была только генерация лиц в стиле «мульт» — с разноцветными глазами, волосами и карикатурными чертами, а после задумался и об аксессуарах — очки, румяна, веснушки и т.д…
На скорую руку набросал мордочки,
и принялся за различные части лица. Начнем с глаз.
Базовая форма для глаза — капля.
В общем-то, эта форма является базовой для многих частей аватарки — ноздри, губы и т.д. Получить ее довольно просто — из параболы. Точнее — из четырех:
/* $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);
А imagefilledpolygon заполняет многоугольник выбранным цветом в контуре, заданным массивом точек в декартовой системе координат. Подробнее о рисовании средствами PHP можно почитать здесь.
Делаем тонкую обводку глаза черным цветом. imagepolygon — как раз подходит — обвод многоугольника без заливки.
Обводка, тень от века, тени, белОк.
Зрачок и блики рисуем с помощью imagefilledellipse.
Зрачок, блики.
Кастомизация глаз происхоит с помощью rand
<?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); }
Остальные части лица (кроме волос и аксессуаров) рисуются аналогичным образом. Получается красиво, но есть большой и жирный минус — это очень затратно даже если оптимизировать. А накладывать друг на друга готовые паттерны может и лучше, но скучно и однообразно. Засим откланиваюсь, с наступающим и спасибо за рыбу.
ссылка на оригинал статьи http://habrahabr.ru/post/164243/
Добавить комментарий