initial commit
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*/.idea/
|
||||
*-assets/
|
||||
20
LICENSE
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Levi Lansing
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
35
README.md
@ -1,2 +1,33 @@
|
||||
pixel-avatar-generator
|
||||
======================
|
||||
#Pixel-Style Avatar Generator
|
||||

|
||||
|
||||
I needed a kid-friendly (G rated) avatar generator, preferably PHP based. Inspired by the randomly generated github avatars, but unable to find a satisfactory pre-made solution, I did what I always do and took on the challenge from scratch. Here's the results of my simple PG-rated pixel-style avatar generator, with billions of possible combinations!
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
##Usage
|
||||
It should be pretty straightforward to use-
|
||||
|
||||
```
|
||||
// Avatar::render($size = 400, $gender = null, $id = null)
|
||||
Avatar::render(200, 'male', 'some-reusable-identifier');
|
||||
```
|
||||
By using an identifier, you can re-generate the identical avatar by sending the same identifier (and gender) later. For my own purposes size is limited to 512 max width/height for performance reasons, but if you plan to generate and cache the avatars, you can go as big as you like!
|
||||
|
||||
If you want to use the output rather than render directly to the output stream, use `Avatar::generate` which returns the image resource.
|
||||
|
||||
##Photoshop file included
|
||||
Under `graphics/` you'll find `avatars.psd`, a complete photoshop file that produced the layers using the image assets generator. You can add and remove layers, regenerate the layers and then replace the `images/` folder to use your own set. Just make sure the file names begin with the layer name. include `_m`, `_f`, or `_mf` at the end of the file name to designate the layer for Males, Females, or both respectively.
|
||||
|
||||
The generator is set to 20x20px layer sizes. If you create a brand new set with a different resolution you'll want to change the `AVATAR_SIZE` constant in avatar.php.
|
||||
|
||||
##More Examples
|
||||

|
||||
|
||||
Enjoy!
|
||||
|
||||
Licensed under the MIT licence. See LICENSE for details.
|
||||
|
||||
233
generator/avatars.php
Normal file
@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class Avatar
|
||||
* a static class for generating avatars from image layers
|
||||
*/
|
||||
class Avatar {
|
||||
const MAX_SIZE = 512;
|
||||
const AVATAR_SIZE = 20;
|
||||
private static $layers = ['background', 'skin', 'mouth', 'eyes', 'brow', 'face', 'facewear', 'shirt', 'hair'];
|
||||
private static $hairColors = [[240,212,83], [62,33,21], [100,23,15], [143,140,137], [112,83,39], [135,71,0], [129,81,57], [self::AVATAR_SIZE, self::AVATAR_SIZE, self::AVATAR_SIZE]];
|
||||
private static $eyeColors = [[1, 101, 59],[66,79,1],[66,66,66],[39,39,39],[0,82,156],[76,44,4],[0,59,108],[0,93,128],[93,105,29]];
|
||||
private static $browColor = [99, 54, 32];
|
||||
|
||||
/**
|
||||
* render an avatar as a png straight to the browser
|
||||
* @param int $size
|
||||
* @param string $gender
|
||||
* @param string $id
|
||||
*/
|
||||
public static function render($size = 400, $gender = null, $id = null) {
|
||||
header("Content-type: image/png");
|
||||
if ($gender != 'male' && $gender != 'female') {
|
||||
$gender = mt_rand(0,1) ? 'male' : 'female';
|
||||
}
|
||||
$avatar = self::generate($size, $gender, $id);
|
||||
imagepng($avatar);
|
||||
imagedestroy($avatar);
|
||||
}
|
||||
|
||||
/**
|
||||
* generate an avatar from the layers.
|
||||
* @param int $size
|
||||
* @param string $gender
|
||||
* @param null $id
|
||||
* @return resource image
|
||||
*/
|
||||
public static function generate($size = 400, $gender = 'male', $id = null) {
|
||||
$size = max(1,min($size, self::MAX_SIZE));
|
||||
if (is_null($id)) {
|
||||
$id = rand(0,getrandmax());
|
||||
}
|
||||
if ($id)
|
||||
srand(base_convert(substr(md5($id), 0, 8), 16, 10));
|
||||
|
||||
$layerList = self::getLayerList();
|
||||
$imgPath = __DIR__ . DIRECTORY_SEPARATOR . 'layers' . DIRECTORY_SEPARATOR;
|
||||
|
||||
// create a transparent base avatar image
|
||||
$avatar = imagecreatetruecolor(self::AVATAR_SIZE,self::AVATAR_SIZE);
|
||||
imageSaveAlpha($avatar, true);
|
||||
imagefill($avatar, 0, 0, 0x7f << 24);
|
||||
|
||||
// add each layer
|
||||
$browColor = self::$browColor;
|
||||
$hairColor = self::$hairColors[rand(0, count(self::$hairColors)-1)];
|
||||
$eyeColor = self::$eyeColors[rand(0, count(self::$eyeColors)-1)];
|
||||
$background = null;
|
||||
foreach (self::$layers as $layer) {
|
||||
$file = $layerList[$layer][$gender][rand(0, count($layerList[$layer][$gender])-1)];
|
||||
$img = imagecreatefrompng($imgPath . $file);
|
||||
if ($layer == 'hair' || ($gender=='male' && $layer=='face')) {
|
||||
self::recolor($img, $hairColor);
|
||||
}
|
||||
if ($layer == 'eyes') {
|
||||
self::recolor($img, $eyeColor, true);
|
||||
}
|
||||
if ($layer == 'brow') {
|
||||
self::recolor($img, [$browColor[0]+$hairColor[0]/2, $browColor[1]+$hairColor[1]/2, $browColor[2]+$hairColor[2]/2], true);
|
||||
}
|
||||
if ($layer == 'background') {
|
||||
$background = $img;
|
||||
continue;
|
||||
}
|
||||
if (rand(0,1) == 0)
|
||||
imageflip($img, IMG_FLIP_HORIZONTAL);
|
||||
imagecopy($avatar, $img, 0, 0, 0, 0, self::AVATAR_SIZE, self::AVATAR_SIZE);
|
||||
imagedestroy($img);
|
||||
}
|
||||
|
||||
// create the output avatar at full size
|
||||
$avatarLarge = imagecreatetruecolor($size, $size);
|
||||
|
||||
if (!is_null($background))
|
||||
imagecopyresized($avatarLarge, $background, 0, 0, 0, 0, $size, $size, self::AVATAR_SIZE, self::AVATAR_SIZE);
|
||||
|
||||
// add the shadow
|
||||
$shadow = self::makeShadowLayer($avatar, 110, $size, $size);
|
||||
$offsetX = ceil(.4/self::AVATAR_SIZE*$size);
|
||||
$offsetY = ceil(1.3/self::AVATAR_SIZE*$size);
|
||||
imagecopy($avatarLarge, $shadow, $offsetX, $offsetY, 0, 0, $size, $size);
|
||||
imagedestroy($shadow);
|
||||
|
||||
// add an outline
|
||||
$outline = self::makeOutlineLayer($avatar, 0x00222222, .1/self::AVATAR_SIZE*$size+.75, $size, $size);
|
||||
imagecopy($avatarLarge, $outline, 0, 0, 0, 0, $size, $size);
|
||||
imagedestroy($outline);
|
||||
|
||||
imagecopyresized($avatarLarge, $avatar, 0, 0, 0, 0, $size, $size, self::AVATAR_SIZE, self::AVATAR_SIZE);
|
||||
imagedestroy($avatar);
|
||||
return $avatarLarge;
|
||||
}
|
||||
|
||||
/**
|
||||
* recolor a layer using the alpha channel
|
||||
* @param $img
|
||||
* @param $newColor
|
||||
* @param bool $ignoreWhite
|
||||
*/
|
||||
private static function recolor($img, $newColor, $ignoreWhite=false) {
|
||||
for ($x=0; $x<self::AVATAR_SIZE; $x++) {
|
||||
for ($y=0; $y<self::AVATAR_SIZE; $y++) {
|
||||
$c = imagecolorsforindex($img, imagecolorat($img, $x, $y));
|
||||
if ($c['alpha'] < 127 && (!$ignoreWhite || $c['red'] != 255 || $c['green'] != 255 || $c['blue'] != 255)) {
|
||||
imagesetpixel($img, $x, $y, imagecolorallocatealpha($img, $newColor[0], $newColor[1], $newColor[2], $c['alpha']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create a semi-transparent black layer to be used as a drop shadow using the alpha chanel
|
||||
* @param $img
|
||||
* @param $alpha
|
||||
* @param $width
|
||||
* @param $height
|
||||
* @return resource
|
||||
*/
|
||||
private static function makeShadowLayer($img, $alpha, $width, $height) {
|
||||
$newImg = imagecreatetruecolor(self::AVATAR_SIZE, self::AVATAR_SIZE);
|
||||
imageSaveAlpha($newImg, true);
|
||||
imagefill($newImg, 0, 0, 0x7f << 24);
|
||||
for ($x=0; $x<self::AVATAR_SIZE; $x++) {
|
||||
for ($y=0; $y<self::AVATAR_SIZE; $y++) {
|
||||
$c = imagecolorsforindex($img, imagecolorat($img, $x, $y));
|
||||
if ($c['alpha'] < 100) {
|
||||
imagesetpixel($newImg, $x, $y, ($alpha & 0x7f) << 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
$fullSize = imagecreatetruecolor($width, $height);
|
||||
imageSaveAlpha($fullSize, true);
|
||||
imagefill($fullSize, 0, 0, 0x7f << 24);
|
||||
imagecopyresized($fullSize, $newImg, 0, 0, 0, 0, $width, $height, self::AVATAR_SIZE, self::AVATAR_SIZE);
|
||||
imagedestroy($newImg);
|
||||
return $fullSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* draw an outline around the non-transparent pixels
|
||||
* @param $img
|
||||
* @param $color
|
||||
* @param $thickness
|
||||
* @param $width
|
||||
* @param $height
|
||||
* @return resource
|
||||
*/
|
||||
private static function makeOutlineLayer($img, $color, $thickness, $width, $height) {
|
||||
$thickness = (int)$thickness;
|
||||
$newImg = imagecreatetruecolor(self::AVATAR_SIZE, self::AVATAR_SIZE);
|
||||
imageSaveAlpha($newImg, true);
|
||||
imagefill($newImg, 0, 0, 0x7f << 24);
|
||||
for ($x=0; $x<self::AVATAR_SIZE; $x++) {
|
||||
for ($y=0; $y<self::AVATAR_SIZE; $y++) {
|
||||
$c = imagecolorsforindex($img, imagecolorat($img, $x, $y));
|
||||
if ($c['alpha'] < 100) {
|
||||
imagesetpixel($newImg, $x, $y, $color);
|
||||
}
|
||||
}
|
||||
}
|
||||
$fullSize = imagecreatetruecolor($width, $height);
|
||||
imageSaveAlpha($fullSize, true);
|
||||
imagefill($fullSize, 0, 0, 0x7f << 24);
|
||||
imagecopyresized($fullSize, $newImg, $thickness, $thickness, 0, 0, $width, $height, self::AVATAR_SIZE, self::AVATAR_SIZE);
|
||||
imagecopy($fullSize, $fullSize, 0, -$thickness*2, 0, 0, $width, $height);
|
||||
imagecopy($fullSize, $fullSize, -$thickness*2, 0, 0, 0, $width, $height);
|
||||
imagedestroy($newImg);
|
||||
return $fullSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate the list of layer files by layer name and gender
|
||||
* @return array
|
||||
*/
|
||||
private static function getLayerList() {
|
||||
$list = array_fill_keys(self::$layers, null);
|
||||
$list = array_map(function() { return ['male' => [], 'female'=>[]]; }, $list);
|
||||
foreach (scandir(__DIR__ . DIRECTORY_SEPARATOR . 'layers') as $file) {
|
||||
$layer = self::findLayer($file);
|
||||
if ($layer) {
|
||||
if (self::isForMale($file))
|
||||
$list[$layer]['male'][] = $file;
|
||||
if (self::isForFemale($file))
|
||||
$list[$layer]['female'][] = $file;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* determine the layer name from a file name
|
||||
* @param $fileName
|
||||
* @return null|string
|
||||
*/
|
||||
private static function findLayer($fileName) {
|
||||
$found = '';
|
||||
foreach (self::$layers as $layer) {
|
||||
if (substr_compare($layer, $fileName, 0, strlen($layer), true) == 0) {
|
||||
if (strlen($layer) > strlen($found))
|
||||
$found = $layer;
|
||||
}
|
||||
}
|
||||
return $found == '' ? null : $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* determine if the file is meant for male avatars
|
||||
* @param $fileName
|
||||
* @return bool
|
||||
*/
|
||||
private static function isForMale($fileName) {
|
||||
return (preg_match('/_f?mf?\.png/', $fileName) > 0 || preg_match('/_[mf]+\.png/', $fileName) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* determine if the file is meant for female avatars
|
||||
* @param $fileName
|
||||
* @return bool
|
||||
*/
|
||||
private static function isForFemale($fileName) {
|
||||
return (preg_match('/_m?fm?\.png/', $fileName) > 0 || preg_match('/_[mf]+\.png/', $fileName) == 0);
|
||||
}
|
||||
}
|
||||
4
generator/index.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
require 'avatars.php';
|
||||
Avatar::render();
|
||||
?>
|
||||
BIN
generator/layers/background0.png
Normal file
|
After Width: | Height: | Size: 897 B |
BIN
generator/layers/background1.png
Normal file
|
After Width: | Height: | Size: 692 B |
BIN
generator/layers/background2.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
generator/layers/background3.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
generator/layers/background4.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
generator/layers/background5.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
generator/layers/background6.png
Normal file
|
After Width: | Height: | Size: 792 B |
BIN
generator/layers/background7.png
Normal file
|
After Width: | Height: | Size: 792 B |
BIN
generator/layers/background8.png
Normal file
|
After Width: | Height: | Size: 792 B |
BIN
generator/layers/background9.png
Normal file
|
After Width: | Height: | Size: 792 B |
BIN
generator/layers/brow2_mf.png
Normal file
|
After Width: | Height: | Size: 300 B |
BIN
generator/layers/brow2a_mf.png
Normal file
|
After Width: | Height: | Size: 301 B |
BIN
generator/layers/brow2b_mf.png
Normal file
|
After Width: | Height: | Size: 304 B |
BIN
generator/layers/brow3_mf.png
Normal file
|
After Width: | Height: | Size: 300 B |
BIN
generator/layers/brow3a_mf.png
Normal file
|
After Width: | Height: | Size: 304 B |
BIN
generator/layers/brow4_mf.png
Normal file
|
After Width: | Height: | Size: 305 B |
BIN
generator/layers/brow5_f.png
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
generator/layers/brow6_m.png
Normal file
|
After Width: | Height: | Size: 311 B |
BIN
generator/layers/eyes1.png
Normal file
|
After Width: | Height: | Size: 304 B |
BIN
generator/layers/eyes2.png
Normal file
|
After Width: | Height: | Size: 305 B |
BIN
generator/layers/eyes3.png
Normal file
|
After Width: | Height: | Size: 308 B |
BIN
generator/layers/eyes4.png
Normal file
|
After Width: | Height: | Size: 308 B |
BIN
generator/layers/eyes4a.png
Normal file
|
After Width: | Height: | Size: 309 B |
BIN
generator/layers/eyes4b.png
Normal file
|
After Width: | Height: | Size: 309 B |
BIN
generator/layers/eyes4c.png
Normal file
|
After Width: | Height: | Size: 308 B |
BIN
generator/layers/eyes5.png
Normal file
|
After Width: | Height: | Size: 305 B |
BIN
generator/layers/eyes5a.png
Normal file
|
After Width: | Height: | Size: 305 B |
BIN
generator/layers/eyes6.png
Normal file
|
After Width: | Height: | Size: 304 B |
BIN
generator/layers/eyes7.png
Normal file
|
After Width: | Height: | Size: 304 B |
BIN
generator/layers/face-none_mf.png
Normal file
|
After Width: | Height: | Size: 303 B |
BIN
generator/layers/face10_m.png
Normal file
|
After Width: | Height: | Size: 301 B |
BIN
generator/layers/face1_f.png
Normal file
|
After Width: | Height: | Size: 302 B |
BIN
generator/layers/face1_m.png
Normal file
|
After Width: | Height: | Size: 305 B |
BIN
generator/layers/face2_f.png
Normal file
|
After Width: | Height: | Size: 310 B |
BIN
generator/layers/face2_m.png
Normal file
|
After Width: | Height: | Size: 314 B |
BIN
generator/layers/face3_f.png
Normal file
|
After Width: | Height: | Size: 320 B |
BIN
generator/layers/face3_m.png
Normal file
|
After Width: | Height: | Size: 298 B |
BIN
generator/layers/face4_f.png
Normal file
|
After Width: | Height: | Size: 301 B |
BIN
generator/layers/face4_m.png
Normal file
|
After Width: | Height: | Size: 312 B |
BIN
generator/layers/face5_f.png
Normal file
|
After Width: | Height: | Size: 303 B |
BIN
generator/layers/face5_m.png
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
generator/layers/face6_m.png
Normal file
|
After Width: | Height: | Size: 304 B |
BIN
generator/layers/face7_m.png
Normal file
|
After Width: | Height: | Size: 321 B |
BIN
generator/layers/face8_m.png
Normal file
|
After Width: | Height: | Size: 310 B |
BIN
generator/layers/face9_m.png
Normal file
|
After Width: | Height: | Size: 301 B |
BIN
generator/layers/facewear0-none1_mf.png
Normal file
|
After Width: | Height: | Size: 303 B |
BIN
generator/layers/facewear0-none2_mf.png
Normal file
|
After Width: | Height: | Size: 303 B |
BIN
generator/layers/facewear0-none3_mf.png
Normal file
|
After Width: | Height: | Size: 303 B |
BIN
generator/layers/facewear0-none4_mf.png
Normal file
|
After Width: | Height: | Size: 303 B |
BIN
generator/layers/facewear0-none5_mf.png
Normal file
|
After Width: | Height: | Size: 303 B |
BIN
generator/layers/facewear0-none_mf.png
Normal file
|
After Width: | Height: | Size: 303 B |
BIN
generator/layers/facewear10_f.png
Normal file
|
After Width: | Height: | Size: 302 B |
BIN
generator/layers/facewear11_f.png
Normal file
|
After Width: | Height: | Size: 339 B |
BIN
generator/layers/facewear11a_f.png
Normal file
|
After Width: | Height: | Size: 339 B |
BIN
generator/layers/facewear12_f.png
Normal file
|
After Width: | Height: | Size: 346 B |
BIN
generator/layers/facewear13_f.png
Normal file
|
After Width: | Height: | Size: 301 B |
BIN
generator/layers/facewear14_f.png
Normal file
|
After Width: | Height: | Size: 308 B |
BIN
generator/layers/facewear15_f.png
Normal file
|
After Width: | Height: | Size: 301 B |
BIN
generator/layers/facewear1a_mf.png
Normal file
|
After Width: | Height: | Size: 340 B |
BIN
generator/layers/facewear1b_mf.png
Normal file
|
After Width: | Height: | Size: 346 B |
BIN
generator/layers/facewear2_m.png
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
generator/layers/facewear3_mf.png
Normal file
|
After Width: | Height: | Size: 337 B |
BIN
generator/layers/facewear4_mf.png
Normal file
|
After Width: | Height: | Size: 357 B |
BIN
generator/layers/facewear5_mf.png
Normal file
|
After Width: | Height: | Size: 358 B |
BIN
generator/layers/facewear6_m.png
Normal file
|
After Width: | Height: | Size: 300 B |
BIN
generator/layers/facewear7_f.png
Normal file
|
After Width: | Height: | Size: 302 B |
BIN
generator/layers/facewear8_f.png
Normal file
|
After Width: | Height: | Size: 301 B |
BIN
generator/layers/facewear9_f.png
Normal file
|
After Width: | Height: | Size: 301 B |
BIN
generator/layers/hair0_m.png
Normal file
|
After Width: | Height: | Size: 322 B |
BIN
generator/layers/hair10_f.png
Normal file
|
After Width: | Height: | Size: 326 B |
BIN
generator/layers/hair11_f.png
Normal file
|
After Width: | Height: | Size: 340 B |
BIN
generator/layers/hair12_f.png
Normal file
|
After Width: | Height: | Size: 335 B |
BIN
generator/layers/hair13_f.png
Normal file
|
After Width: | Height: | Size: 338 B |
BIN
generator/layers/hair14_f.png
Normal file
|
After Width: | Height: | Size: 336 B |
BIN
generator/layers/hair15_m.png
Normal file
|
After Width: | Height: | Size: 308 B |
BIN
generator/layers/hair16_f.png
Normal file
|
After Width: | Height: | Size: 337 B |
BIN
generator/layers/hair16_m.png
Normal file
|
After Width: | Height: | Size: 312 B |
BIN
generator/layers/hair17_f.png
Normal file
|
After Width: | Height: | Size: 334 B |
BIN
generator/layers/hair17_m.png
Normal file
|
After Width: | Height: | Size: 330 B |
BIN
generator/layers/hair18_f.png
Normal file
|
After Width: | Height: | Size: 338 B |
BIN
generator/layers/hair18_m.png
Normal file
|
After Width: | Height: | Size: 314 B |
BIN
generator/layers/hair19_f.png
Normal file
|
After Width: | Height: | Size: 341 B |
BIN
generator/layers/hair19_m.png
Normal file
|
After Width: | Height: | Size: 315 B |
BIN
generator/layers/hair1_m.png
Normal file
|
After Width: | Height: | Size: 323 B |
BIN
generator/layers/hair20_f.png
Normal file
|
After Width: | Height: | Size: 343 B |
BIN
generator/layers/hair20_m.png
Normal file
|
After Width: | Height: | Size: 308 B |
BIN
generator/layers/hair21_f.png
Normal file
|
After Width: | Height: | Size: 334 B |
BIN
generator/layers/hair21_m.png
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
generator/layers/hair22_f.png
Normal file
|
After Width: | Height: | Size: 335 B |
BIN
generator/layers/hair23_f.png
Normal file
|
After Width: | Height: | Size: 345 B |
BIN
generator/layers/hair24_f.png
Normal file
|
After Width: | Height: | Size: 349 B |
BIN
generator/layers/hair2_m.png
Normal file
|
After Width: | Height: | Size: 310 B |
BIN
generator/layers/hair3_m.png
Normal file
|
After Width: | Height: | Size: 315 B |
BIN
generator/layers/hair4_m.png
Normal file
|
After Width: | Height: | Size: 314 B |
BIN
generator/layers/hair5_m.png
Normal file
|
After Width: | Height: | Size: 317 B |