Генерация аватарок средствами PHP, глаза

от автора



Как и перед авторами недавнего топика, передо мной возник вопрос генерации дефолтных аватаров. Тут же вспомнил о «фрактальных» аватарах.

Основной принцип — генерируем примитивами 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

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); } 

Остальные части лица (кроме волос и аксессуаров) рисуются аналогичным образом. Получается красиво, но есть большой и жирный минус — это очень затратно даже если оптимизировать. А накладывать друг на друга готовые паттерны может и лучше, но скучно и однообразно. Засим откланиваюсь, с наступающим и спасибо за рыбу.

ссылка на оригинал статьи http://habrahabr.ru/post/164243/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *