├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── python-publish.yml ├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── examples ├── avatar │ ├── __main__.py │ └── my_avatar.svg ├── banner │ ├── __main__.py │ └── banner.png ├── install │ ├── __main__.py │ ├── avatar_suit.svg │ ├── install.py │ └── suit.svg ├── random │ ├── __main__.py │ ├── avatar_0.svg │ ├── avatar_1.svg │ ├── avatar_2.svg │ ├── avatar_3.svg │ ├── avatar_4.svg │ ├── avatar_5.svg │ ├── avatar_6.svg │ ├── avatar_7.svg │ ├── avatar_8.svg │ └── avatar_9.svg ├── random_gif_apng │ ├── avatars.gif │ ├── avatars.png │ ├── gif.py │ └── png.py ├── reset │ └── __main__.py ├── shirt_text │ ├── __main__.py │ └── avatar_text.svg └── uninstall │ └── __main__.py ├── python_avatars ├── __init__.py ├── __main__.py ├── accessory_types.py ├── avatar.py ├── avatar_parts │ ├── accessories │ │ ├── eyepatch.svg │ │ ├── kurt.svg │ │ ├── prescription_01.svg │ │ ├── prescription_02.svg │ │ ├── round.svg │ │ ├── sunglasses.svg │ │ ├── sunglasses_2.svg │ │ ├── wayfarers.svg │ │ └── wayfarers_2.svg │ ├── clothes │ │ ├── astronaut_suit.svg │ │ ├── blazer_shirt.svg │ │ ├── blazer_sweater.svg │ │ ├── bond_suit.svg │ │ ├── chef.svg │ │ ├── collar_sweater.svg │ │ ├── gladiator.svg │ │ ├── graphic │ │ │ ├── bat.svg │ │ │ ├── bear.svg │ │ │ ├── cumbia.svg │ │ │ ├── custom_text.svg │ │ │ ├── deer.svg │ │ │ ├── diamond.svg │ │ │ ├── hola.svg │ │ │ ├── pizza.svg │ │ │ ├── resist.svg │ │ │ ├── selena.svg │ │ │ ├── skull.svg │ │ │ └── skull_outline.svg │ │ ├── graphic_shirt.svg │ │ ├── hoodie.svg │ │ ├── jedi_robe.svg │ │ ├── overall.svg │ │ ├── shirt_crew_neck.svg │ │ ├── shirt_scoop_neck.svg │ │ ├── shirt_v_neck.svg │ │ └── shirt_wick.svg │ ├── eyebrows │ │ ├── angry.svg │ │ ├── angry_natural.svg │ │ ├── default.svg │ │ ├── default_natural.svg │ │ ├── flat_natural.svg │ │ ├── frown_natural.svg │ │ ├── raised_excited.svg │ │ ├── raised_excited_natural.svg │ │ ├── sad_concerned.svg │ │ ├── sad_concerned_natural.svg │ │ ├── unibrow_natural.svg │ │ ├── up_down.svg │ │ └── up_down_natural.svg │ ├── eyes │ │ ├── closed.svg │ │ ├── cry.svg │ │ ├── default.svg │ │ ├── eye_roll.svg │ │ ├── happy.svg │ │ ├── heart.svg │ │ ├── side.svg │ │ ├── squint.svg │ │ ├── surprised.svg │ │ ├── wink.svg │ │ ├── wink_wacky.svg │ │ └── x_dizzy.svg │ ├── facial_hair │ │ ├── beard_light.svg │ │ ├── beard_magestic.svg │ │ ├── beard_medium.svg │ │ ├── einstien_mustache.svg │ │ ├── moustache_fancy.svg │ │ ├── moustache_magnum.svg │ │ └── wick_beard.svg │ ├── mouth │ │ ├── big_smile.svg │ │ ├── concerned.svg │ │ ├── default.svg │ │ ├── disbelief.svg │ │ ├── eating.svg │ │ ├── grimace.svg │ │ ├── sad.svg │ │ ├── scream_open.svg │ │ ├── serious.svg │ │ ├── smile.svg │ │ ├── tongue.svg │ │ ├── twinkle.svg │ │ └── vomit.svg │ ├── nose │ │ ├── default.svg │ │ ├── small.svg │ │ └── wide.svg │ ├── styles │ │ ├── circle.svg │ │ └── transparent.svg │ └── top │ │ ├── hair │ │ ├── astronout.svg │ │ ├── big_hair.svg │ │ ├── bob.svg │ │ ├── braids.svg │ │ ├── bride.svg │ │ ├── bun.svg │ │ ├── buzzcut.svg │ │ ├── caesar.svg │ │ ├── caesar_side_part.svg │ │ ├── cornrows.svg │ │ ├── curly.svg │ │ ├── curly_2.svg │ │ ├── curvy.svg │ │ ├── dreadlocks.svg │ │ ├── dreads.svg │ │ ├── einstein_hair.svg │ │ ├── elvis.svg │ │ ├── evil_spike.svg │ │ ├── frida.svg │ │ ├── frizzle.svg │ │ ├── fro.svg │ │ ├── fro_band.svg │ │ ├── half_shaved.svg │ │ ├── hat.svg │ │ ├── long_hair_curly.svg │ │ ├── long_not_too_long.svg │ │ ├── loose_hair.svg │ │ ├── mia_wallace.svg │ │ ├── mohawk.svg │ │ ├── mowgli.svg │ │ ├── no_hair.svg │ │ ├── pixie.svg │ │ ├── pompadour.svg │ │ ├── quiff.svg │ │ ├── shaggy.svg │ │ ├── shaggy_mullet.svg │ │ ├── shaved_sides.svg │ │ ├── short_curly.svg │ │ ├── short_dreads_1.svg │ │ ├── short_dreads_2.svg │ │ ├── short_flat.svg │ │ ├── short_round.svg │ │ ├── short_waved.svg │ │ ├── sides.svg │ │ ├── straight_1.svg │ │ ├── straight_2.svg │ │ ├── straight_strand.svg │ │ ├── twist_long_hair.svg │ │ ├── twist_long_hair_2.svg │ │ ├── wick.svg │ │ └── wild.svg │ │ └── hat │ │ ├── chef_cap.svg │ │ ├── gladiator_helmet.svg │ │ ├── hat.svg │ │ ├── hijab.svg │ │ ├── jedi.svg │ │ ├── turban.svg │ │ ├── winter_hat_1.svg │ │ ├── winter_hat_2.svg │ │ ├── winter_hat_3.svg │ │ └── winter_hat_4.svg ├── avatar_styles.py ├── background_colors.py ├── base_enums.py ├── clothing_colors.py ├── clothing_graphics.py ├── clothing_types.py ├── core.py ├── default.json ├── eye_types.py ├── eyebrow_types.py ├── facial_hair_types.py ├── hair_colors.py ├── hair_types.py ├── hat_types.py ├── mouth_types.py ├── nose_types.py ├── skin_colors.py ├── svg_parser.py └── top_types.py ├── setup.py ├── test └── test_avatar.py └── tools └── downloader.py /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries 3 | 4 | name: Upload Python Package 5 | 6 | on: 7 | push: 8 | tags: 9 | - 'v*' 10 | 11 | jobs: 12 | release: 13 | name: Create Release 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@master 18 | - name: Create Release 19 | id: create_release 20 | uses: actions/create-release@v1 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 | with: 24 | tag_name: ${{ github.ref }} 25 | release_name: Release ${{ github.ref }} 26 | body: | 27 | ## Changes in this Release 28 | draft: false 29 | prerelease: false 30 | deploy: 31 | 32 | runs-on: ubuntu-latest 33 | 34 | steps: 35 | - uses: actions/checkout@v2 36 | - name: Set up Python 37 | uses: actions/setup-python@v2 38 | with: 39 | python-version: '3.x' 40 | - name: Install dependencies 41 | run: | 42 | python -m pip install --upgrade pip 43 | pip install setuptools wheel twine 44 | - name: Build and publish 45 | env: 46 | TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} 47 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 48 | run: | 49 | python setup.py sdist bdist_wheel 50 | twine upload dist/* 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **.pyc -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.8" 4 | 5 | # install dependencies 6 | install: 7 | - 'pip install -e .' 8 | 9 | # Perform tests 10 | script: 11 | - 'python -m pytest' -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Ibon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/avatar/__main__.py: -------------------------------------------------------------------------------- 1 | import python_avatars as pa 2 | 3 | pa.Avatar( 4 | style=pa.AvatarStyle.CIRCLE, 5 | top=pa.HairType.STRAIGHT_2, 6 | eyebrows=pa.EyebrowType.DEFAULT_NATURAL, 7 | eyes=pa.EyeType.DEFAULT, 8 | nose=pa.NoseType.DEFAULT, 9 | mouth=pa.MouthType.EATING, 10 | facial_hair=pa.FacialHairType.NONE, 11 | # You can use hex colors on any color attribute... 12 | skin_color='#00FFFF', 13 | # Or you can use the colors provided by the library 14 | hair_color=pa.HairColor.BLACK, 15 | accessory=pa.AccessoryType.NONE, 16 | clothing=pa.ClothingType.HOODIE, 17 | clothing_color=pa.ClothingColor.HEATHER 18 | ).render("my_avatar.svg") 19 | -------------------------------------------------------------------------------- /examples/banner/__main__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import python_avatars as pa 4 | from cairosvg import svg2png 5 | from PIL import Image, ImageDraw, ImageFont, ImageFilter 6 | 7 | # The script used to generate the social preview image for this repository 8 | # NOTE By default it will generate the image without the text overlay. 9 | # If you wish to generate it with text, you will need to set the variable 10 | # below to `True` and place the ttf files for Roboto in examples/banner/roboto/ 11 | add_text_overlay = False 12 | 13 | image = Image.new('RGBA', (1280, 640), (255, 255, 255, 255)) 14 | 15 | fns = [] 16 | x = -100 17 | y = -100 18 | row = 0 19 | for i in range(40): 20 | # Store filename 21 | fn = "avatar_{}.png".format(i) 22 | fns.append(fn) 23 | 24 | # Convert and save png 25 | svg = pa.Avatar.random( 26 | style=pa.AvatarStyle.pick_random( 27 | favor=pa.AvatarStyle.TRANSPARENT) 28 | 29 | ).render() 30 | svg2png(svg, write_to=fn) 31 | 32 | # Load png 33 | avatar_img = Image.open(fn) 34 | 35 | # Create the point where the image will be pasted 36 | pt = (x, y) 37 | x += int(avatar_img.size[0] * 0.7) 38 | if x >= image.size[0]: 39 | if row % 2 == 0: 40 | x = 0 41 | else: 42 | x = -avatar_img.size[0] // 2 43 | y += int(avatar_img.size[1] * 0.6) 44 | row += 1 45 | 46 | # Paste the image 47 | image.paste(avatar_img, pt, mask=avatar_img) 48 | 49 | # Add text overlay 50 | if add_text_overlay: 51 | rect = (0, 0, 1280, 200) 52 | font_title = ImageFont.truetype('examples/banner/roboto/Roboto-Black.ttf', 65) 53 | font_main = ImageFont.truetype('examples/banner/roboto/Roboto-Regular.ttf', 40) 54 | font_small = ImageFont.truetype('examples/banner/roboto/Roboto-Thin.ttf', 30) 55 | 56 | overlay = Image.new('RGBA', (1280, 640), (0, 0, 0, 0)) 57 | id = ImageDraw.Draw(overlay) 58 | 59 | # Blur rectangle 60 | crop_rect = image.crop(rect) 61 | crop_rect = crop_rect.filter(ImageFilter.BLUR) 62 | image.paste(crop_rect, rect) 63 | 64 | # Draw semi-transparent overlay over the blurred part 65 | id.rectangle(rect, fill=(255, 255, 255, 200)) 66 | 67 | # Draw text 68 | start_y = 20 69 | texts = [ 70 | ("python-avatars", font_title, (54, 69, 79)), 71 | ("SVG avatar package for Python", font_main, (79, 79, 79)), 72 | (f"Version {pa.__version__}", font_small, (0, 0, 0)), 73 | ] 74 | for text, font, color in texts: 75 | id.text((30, start_y), text, fill=color, font=font) 76 | width, height = font.getsize(text) 77 | start_y += height 78 | 79 | # Combine image and overlay 80 | image = Image.alpha_composite(image, overlay) 81 | 82 | image.save("banner.png", "PNG") 83 | 84 | # Remove all the generated png files 85 | for fn in fns: 86 | os.remove(fn) 87 | -------------------------------------------------------------------------------- /examples/banner/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibonn/python_avatars/179ab470ab1a37e6d25091e83948ae1494ebc20f/examples/banner/banner.png -------------------------------------------------------------------------------- /examples/install/__main__.py: -------------------------------------------------------------------------------- 1 | import python_avatars as pa 2 | 3 | # IMPORTANT: You should run install.py before running this script, otherwise it won't work. 4 | 5 | try: 6 | # Generate a random avatar wearing the new installed clothes 7 | pa.Avatar.random(clothing=pa.ClothingType.SUIT).render("avatar_suit.svg") 8 | except AttributeError: 9 | print("The part is not installed. Please run install.py to install it") 10 | -------------------------------------------------------------------------------- /examples/install/install.py: -------------------------------------------------------------------------------- 1 | import python_avatars as pa 2 | 3 | # Install the new part 4 | pa.install_part('suit.svg', pa.ClothingType) 5 | -------------------------------------------------------------------------------- /examples/random/__main__.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | from python_avatars import Avatar 4 | 5 | # Set a seed 6 | random.seed(123) 7 | 8 | # Generate 10 random avatars 9 | for i in range(10): 10 | Avatar.random().render('avatar_{}.svg'.format(i)) 11 | -------------------------------------------------------------------------------- /examples/random_gif_apng/avatars.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibonn/python_avatars/179ab470ab1a37e6d25091e83948ae1494ebc20f/examples/random_gif_apng/avatars.gif -------------------------------------------------------------------------------- /examples/random_gif_apng/avatars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibonn/python_avatars/179ab470ab1a37e6d25091e83948ae1494ebc20f/examples/random_gif_apng/avatars.png -------------------------------------------------------------------------------- /examples/random_gif_apng/gif.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from PIL import Image 4 | from cairosvg import svg2png 5 | from python_avatars import Avatar 6 | 7 | # IMPORTANT: This example requires 'PIL (Pillow)' to work 8 | # 9 | # >> pip install Pillow 10 | 11 | # Generate 30 random avatars 12 | imgs = [] 13 | fns = [] 14 | for i in range(30): 15 | 16 | fn = 'avatar_{}.gif'.format(i) 17 | 18 | avatar_svg = Avatar.random().render() 19 | svg2png(avatar_svg, write_to=fn) 20 | 21 | imgs.append(Image.open(fn).convert('PA')) 22 | fns.append(fn) 23 | 24 | first = imgs[0] 25 | others = imgs[1:] 26 | first.save('avatars.gif', save_all=True, append_images=others, duration=500, disposal=2, loop=0, transparency=0) 27 | 28 | for fn in fns: 29 | os.remove(fn) -------------------------------------------------------------------------------- /examples/random_gif_apng/png.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from apng import APNG 4 | from cairosvg import svg2png 5 | from python_avatars import Avatar 6 | 7 | # IMPORTANT: This example requires 'apng' and 'cairosvg' to work 8 | # 9 | # >> pip install apng cairosvg 10 | 11 | # Generate 30 random avatars 12 | fns = [] 13 | for i in range(30): 14 | 15 | fn = 'avatar_{}.png'.format(i) 16 | 17 | avatar_svg = Avatar.random().render() 18 | svg2png(avatar_svg, write_to=fn) 19 | 20 | # imgs.append(Image.open(fn).convert('PA')) 21 | fns.append(fn) 22 | 23 | # first = imgs[0] 24 | # others = imgs[1:] 25 | # first.save('avatars.gif', save_all=True, append_images=others, duration=500, disposal=2, loop=0, transparency=0) 26 | 27 | APNG.from_files(fns, delay=500).save("avatars.png") 28 | 29 | for fn in fns: 30 | os.remove(fn) 31 | -------------------------------------------------------------------------------- /examples/reset/__main__.py: -------------------------------------------------------------------------------- 1 | from python_avatars import factory_reset 2 | 3 | # WARNING: Running this script will reset the library to its default state. 4 | # This means all the colors and parts (eyes, eyebrows, nose types, 5 | # clothing types...) you installed will be removed. 6 | 7 | factory_reset() -------------------------------------------------------------------------------- /examples/shirt_text/__main__.py: -------------------------------------------------------------------------------- 1 | import python_avatars as pa 2 | 3 | pa.Avatar( 4 | style=pa.AvatarStyle.CIRCLE, 5 | background_color='#FF00FF', 6 | # Choose graphic shirt 7 | clothing=pa.ClothingType.GRAPHIC_SHIRT, 8 | clothing_color=pa.ClothingColor.GRAY_02, 9 | # Important to choose this as shirt_graphic, otherwise shirt_text will be ignored 10 | shirt_graphic=pa.ClothingGraphic.CUSTOM_TEXT, 11 | shirt_text='Chess' 12 | ).render("avatar_text.svg") 13 | -------------------------------------------------------------------------------- /examples/uninstall/__main__.py: -------------------------------------------------------------------------------- 1 | import python_avatars as pa 2 | 3 | # IMPORTANT: You should run the example at examples/install before running this script 4 | 5 | # Uninstall the part installed with install example 6 | pa.uninstall_part(pa.ClothingType.SUIT) 7 | -------------------------------------------------------------------------------- /python_avatars/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | SVG avatar generation library 3 | 4 | More info @ https://github.com/ibonn/python_avatars 5 | """ 6 | 7 | __version__ = "1.4.1" 8 | 9 | # Enums 10 | from .accessory_types import AccessoryType 11 | from .avatar_styles import AvatarStyle 12 | from .background_colors import BackgroundColor 13 | from .clothing_colors import ClothingColor 14 | from .clothing_graphics import ClothingGraphic 15 | from .clothing_types import ClothingType 16 | from .eye_types import EyeType 17 | from .eyebrow_types import EyebrowType 18 | from .facial_hair_types import FacialHairType 19 | from .hair_colors import HairColor 20 | from .hair_types import HairType 21 | from .hat_types import HatType 22 | from .mouth_types import MouthType 23 | from .nose_types import NoseType 24 | from .skin_colors import SkinColor 25 | from .top_types import TopType 26 | 27 | # Classes 28 | from .avatar import Avatar 29 | 30 | # Core functions 31 | from .core import install_part 32 | from .core import install_color 33 | from .core import uninstall_part 34 | from .core import uninstall_color 35 | from .core import factory_reset 36 | -------------------------------------------------------------------------------- /python_avatars/accessory_types.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | 3 | 4 | class AccessoryType(AvatarPart): 5 | """Accessories (Glasses)""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'accessory_types.py' 9 | __path__ = 'avatar_parts/accessories' 10 | 11 | NONE = '' 12 | EYEPATCH = 'eyepatch' 13 | KURT = 'kurt' 14 | PRESCRIPTION_1 = 'prescription_01' 15 | PRESCRIPTION_2 = 'prescription_02' 16 | ROUND = 'round' 17 | SUNGLASSES = 'sunglasses' 18 | WAYFARERS = 'wayfarers' 19 | SUNGLASSES_2 = 'sunglasses_2' 20 | WAYFARERS_2 = 'wayfarers_2' 21 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/accessories/kurt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/accessories/round.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/astronaut_suit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/blazer_shirt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/blazer_sweater.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/bond_suit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/chef.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/collar_sweater.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/graphic/bat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/graphic/bear.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/graphic/custom_text.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hola! 6 | 7 | 8 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/graphic/deer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/graphic/skull.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/graphic_shirt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/hoodie.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/jedi_robe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/overall.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/shirt_crew_neck.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/shirt_scoop_neck.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/shirt_v_neck.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/clothes/shirt_wick.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/angry.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/angry_natural.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/default.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/default_natural.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/flat_natural.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/frown_natural.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/raised_excited.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/raised_excited_natural.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/sad_concerned.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/sad_concerned_natural.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/unibrow_natural.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/up_down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyebrows/up_down_natural.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/closed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/cry.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/default.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/eye_roll.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/happy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/side.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/squint.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/surprised.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/wink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/wink_wacky.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/eyes/x_dizzy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/facial_hair/beard_light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/facial_hair/beard_medium.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/facial_hair/einstien_mustache.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/facial_hair/moustache_fancy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/facial_hair/moustache_magnum.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/facial_hair/wick_beard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/big_smile.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/concerned.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/default.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/disbelief.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/eating.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/grimace.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/sad.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/scream_open.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/serious.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/smile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/tongue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/twinkle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/mouth/vomit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/nose/default.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/nose/small.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/nose/wide.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/bob.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/bride.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/bun.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/buzzcut.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/caesar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/caesar_side_part.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/elvis.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/evil_spike.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/frizzle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/half_shaved.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/hat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/long_not_too_long.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/mia_wallace.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/mohawk.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/mowgli.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/no_hair.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/pixie.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/pompadour.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/quiff.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/shaggy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/short_flat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/short_round.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/short_waved.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/sides.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/straight_1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/straight_2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hair/straight_strand.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hat/hat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hat/jedi.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hat/winter_hat_1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /python_avatars/avatar_parts/top/hat/winter_hat_3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /python_avatars/avatar_styles.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | 3 | 4 | class AvatarStyle(AvatarPart): 5 | """Avatar styles""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'avatar_styles.py' 9 | __path__ = 'avatar_parts/styles' 10 | 11 | TRANSPARENT = 'transparent' 12 | CIRCLE = 'circle' 13 | -------------------------------------------------------------------------------- /python_avatars/background_colors.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarColor 2 | 3 | 4 | class BackgroundColor(AvatarColor): 5 | """Background colors. You can use any other color using its hex code""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'background_colors.py' 9 | 10 | DEFAULT = '#65C9FF' 11 | BLACK = '#262E33' 12 | WHITE = '#FFFFFF' 13 | -------------------------------------------------------------------------------- /python_avatars/base_enums.py: -------------------------------------------------------------------------------- 1 | import enum 2 | import random 3 | 4 | 5 | class AvatarEnum(enum.Enum): 6 | """ 7 | Base enum for the library. Allows picking random elements from the avatar 8 | """ 9 | __path__ = '' 10 | __install__ = False 11 | __enum_path__ = 'base_enums.py' 12 | 13 | @classmethod 14 | def get_all(cls): 15 | """ 16 | Get a list containing all the values for this enum 17 | """ 18 | return list(cls) 19 | 20 | @classmethod 21 | def pick_random(cls, favor=None): 22 | """ 23 | Pick a random value from this enum. The value in ``favor`` has 24 | more chances of being chosen 25 | """ 26 | if favor is None: 27 | return cls.__pick_random() 28 | else: 29 | r = random.uniform(0, 1) 30 | if r > 0.5: 31 | return cls.__pick_random() 32 | else: 33 | return favor 34 | 35 | @classmethod 36 | def __pick_random(cls): 37 | return random.choice(cls.get_all()) 38 | 39 | def __str__(self): 40 | return self.value 41 | 42 | 43 | class AvatarPart(AvatarEnum): 44 | """ 45 | Base enum for avatar parts 46 | """ 47 | pass 48 | 49 | 50 | class AvatarColor(AvatarEnum): 51 | """ 52 | Base enum for avatar colors 53 | """ 54 | pass 55 | -------------------------------------------------------------------------------- /python_avatars/clothing_colors.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarColor 2 | 3 | 4 | class ClothingColor(AvatarColor): 5 | """Clothing colors. You can use any other color using its hex code""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'clothing_colors.py' 9 | 10 | BLACK = '#262E33' 11 | BLUE_01 = '#65C9FF' 12 | BLUE_02 = '#5199E4' 13 | BLUE_03 = '#25557C' 14 | GRAY_01 = '#E6E6E6' 15 | GRAY_02 = '#929598' 16 | HEATHER = '#3C4F5C' 17 | PASTEL_BLUE = '#B1E2FF' 18 | PASTEL_GREEN = '#A7FFC4' 19 | PASTEL_ORANGE = '#FFDEB5' 20 | PASTEL_YELLOW = '#FFFFB1' 21 | PINK = '#FF488E' 22 | RED = '#FF5C5C' 23 | WHITE = '#FFFFFF' 24 | -------------------------------------------------------------------------------- /python_avatars/clothing_graphics.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | 3 | 4 | class ClothingGraphic(AvatarPart): 5 | """Clothing graphics. The graphics printed on the clothing if the selected 6 | clothing type is ClothingType.GRAPHIC_SHIRT""" 7 | 8 | __install__ = True 9 | __enum_path__ = 'clothing_graphics.py' 10 | __path__ = 'avatar_parts/clothes/graphic' 11 | 12 | NONE = '' 13 | BAT = 'bat' 14 | BEAR = 'bear' 15 | CUMBIA = 'cumbia' 16 | CUSTOM_TEXT = 'custom_text' 17 | DEER = 'deer' 18 | DIAMOND = 'diamond' 19 | HOLA = 'hola' 20 | PIZZA = 'pizza' 21 | RESIST = 'resist' 22 | SELENA = 'selena' 23 | SKULL_OUTLINE = 'skull_outline' 24 | SKULL = 'skull' 25 | -------------------------------------------------------------------------------- /python_avatars/clothing_types.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | 3 | 4 | class ClothingType(AvatarPart): 5 | """Clothing types""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'clothing_types.py' 9 | __path__ = 'avatar_parts/clothes' 10 | 11 | NONE = '' 12 | BLAZER_SHIRT = 'blazer_shirt' 13 | BLAZER_SWEATER = 'blazer_sweater' 14 | COLLAR_SWEATER = 'collar_sweater' 15 | GRAPHIC_SHIRT = 'graphic_shirt' 16 | HOODIE = 'hoodie' 17 | OVERALL = 'overall' 18 | SHIRT_CREW_NECK = 'shirt_crew_neck' 19 | SHIRT_SCOOP_NECK = 'shirt_scoop_neck' 20 | SHIRT_V_NECK = 'shirt_v_neck' 21 | ASTRONAUT_SUIT = 'astronaut_suit' 22 | BOND_SUIT = 'bond_suit' 23 | CHEF = 'chef' 24 | GLADIATOR = 'gladiator' 25 | JEDI_ROBE = 'jedi_robe' 26 | SHIRT_WICK = 'shirt_wick' 27 | -------------------------------------------------------------------------------- /python_avatars/eye_types.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | 3 | 4 | class EyeType(AvatarPart): 5 | """Eye types""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'eye_types.py' 9 | __path__ = 'avatar_parts/eyes' 10 | 11 | CLOSED = 'closed' 12 | CRY = 'cry' 13 | DEFAULT = 'default' 14 | EYE_ROLL = 'eye_roll' 15 | HAPPY = 'happy' 16 | HEART = 'heart' 17 | SIDE = 'side' 18 | SQUINT = 'squint' 19 | SURPRISED = 'surprised' 20 | WINK_WACKY = 'wink_wacky' 21 | WINK = 'wink' 22 | X_DIZZY = 'x_dizzy' 23 | -------------------------------------------------------------------------------- /python_avatars/eyebrow_types.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | 3 | 4 | class EyebrowType(AvatarPart): 5 | """Eyebrow types""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'eyebrow_types.py' 9 | __path__ = 'avatar_parts/eyebrows' 10 | 11 | NONE = '' 12 | ANGRY_NATURAL = 'angry_natural' 13 | ANGRY = 'angry' 14 | DEFAULT_NATURAL = 'default_natural' 15 | DEFAULT = 'default' 16 | FLAT_NATURAL = 'flat_natural' 17 | FROWN_NATURAL = 'frown_natural' 18 | RAISED_EXCITED_NATURAL = 'raised_excited_natural' 19 | RAISED_EXCITED = 'raised_excited' 20 | SAD_CONCERNED_NATURAL = 'sad_concerned_natural' 21 | SAD_CONCERNED = 'sad_concerned' 22 | UNIBROW_NATURAL = 'unibrow_natural' 23 | UP_DOWN_NATURAL = 'up_down_natural' 24 | UP_DOWN = 'up_down' 25 | -------------------------------------------------------------------------------- /python_avatars/facial_hair_types.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | 3 | 4 | class FacialHairType(AvatarPart): 5 | """Facial hair types""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'facial_hair_types.py' 9 | __path__ = 'avatar_parts/facial_hair' 10 | 11 | NONE = '' 12 | BEARD_LIGHT = 'beard_light' 13 | BEARD_MAGESTIC = 'beard_magestic' 14 | BEARD_MEDIUM = 'beard_medium' 15 | MOUSTACHE_FANCY = 'moustache_fancy' 16 | MOUSTACHE_MAGNUM = 'moustache_magnum' 17 | EINSTEIN_MOUSTACHE = 'einstien_mustache' 18 | WICK_BEARD = 'wick_beard' 19 | -------------------------------------------------------------------------------- /python_avatars/hair_colors.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarColor 2 | 3 | 4 | class HairColor(AvatarColor): 5 | """Hair/facial hair colors. You can use any other color using its hex code""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'hair_colors.py' 9 | 10 | AUBURN = '#A55728' 11 | BLACK = '#2C1B18' 12 | BLONDE = '#B58143' 13 | BLONDE_GOLDEN = '#D6B370' 14 | BROWN = '#724133' 15 | BROWN_DARK = '#4A312C' 16 | PASTEL_PINK = '#F59797' 17 | PLATINUM = '#ECDCBF' 18 | RED = '#C93305' 19 | SILVER_GRAY = '#E8E1E1' 20 | -------------------------------------------------------------------------------- /python_avatars/hair_types.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | 3 | 4 | class HairType(AvatarPart): 5 | """Hair types""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'hair_types.py' 9 | __path__ = 'avatar_parts/top/hair' 10 | 11 | NONE = 'no_hair' 12 | BIG_HAIR = 'big_hair' 13 | BOB = 'bob' 14 | BUN = 'bun' 15 | CAESAR_SIDE_PART = 'caesar_side_part' 16 | CAESAR = 'caesar' 17 | CURLY = 'curly' 18 | CURVY = 'curvy' 19 | DREADS = 'dreads' 20 | FRIDA = 'frida' 21 | FRIZZLE = 'frizzle' 22 | FRO_BAND = 'fro_band' 23 | FRO = 'fro' 24 | LONG_NOT_TOO_LONG = 'long_not_too_long' 25 | MIA_WALLACE = 'mia_wallace' 26 | SHAGGY_MULLET = 'shaggy_mullet' 27 | SHAGGY = 'shaggy' 28 | SHAVED_SIDES = 'shaved_sides' 29 | SHORT_CURLY = 'short_curly' 30 | SHORT_DREADS_1 = 'short_dreads_1' 31 | SHORT_DREADS_2 = 'short_dreads_2' 32 | SHORT_FLAT = 'short_flat' 33 | SHORT_ROUND = 'short_round' 34 | SHORT_WAVED = 'short_waved' 35 | SIDES = 'sides' 36 | STRAIGHT_1 = 'straight_1' 37 | STRAIGHT_2 = 'straight_2' 38 | STRAIGHT_STRAND = 'straight_strand' 39 | ASTRONAUT = 'astronout' 40 | BRAIDS = 'braids' 41 | BRIDE = 'bride' 42 | BUZZCUT = 'buzzcut' 43 | CORNROWS = 'cornrows' 44 | CURLY_2 = 'curly_2' 45 | DREADLOCKS = 'dreadlocks' 46 | EINSTEIN_HAIR = 'einstein_hair' 47 | ELVIS = 'elvis' 48 | EVIL_SPIKE = 'evil_spike' 49 | HALF_SHAVED = 'half_shaved' 50 | HAT = 'hat' 51 | LONG_HAIR_CURLY = 'long_hair_curly' 52 | LOOSE_HAIR = 'loose_hair' 53 | MOHAWK = 'mohawk' 54 | MOWGLI = 'mowgli' 55 | PIXIE = 'pixie' 56 | POMPADOUR = 'pompadour' 57 | QUIFF = 'quiff' 58 | TWIST_LONG_HAIR = 'twist_long_hair' 59 | TWIST_LONG_HAIR_2 = 'twist_long_hair_2' 60 | WICK = 'wick' 61 | WILD = 'wild' 62 | -------------------------------------------------------------------------------- /python_avatars/hat_types.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | 3 | 4 | class HatType(AvatarPart): 5 | """Hat types""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'hat_types.py' 9 | __path__ = 'avatar_parts/top/hat' 10 | 11 | HAT = 'hat' 12 | HIJAB = 'hijab' 13 | TURBAN = 'turban' 14 | WINTER_HAT_1 = 'winter_hat_1' 15 | WINTER_HAT_2 = 'winter_hat_2' 16 | WINTER_HAT_3 = 'winter_hat_3' 17 | WINTER_HAT_4 = 'winter_hat_4' 18 | CHEF_CAP = 'chef_cap' 19 | JEDI = 'jedi' 20 | GLADIATOR_HELMET = 'gladiator_helmet' 21 | -------------------------------------------------------------------------------- /python_avatars/mouth_types.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | 3 | 4 | class MouthType(AvatarPart): 5 | """Mouth types""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'mouth_types.py' 9 | __path__ = 'avatar_parts/mouth' 10 | 11 | CONCERNED = 'concerned' 12 | DEFAULT = 'default' 13 | DISBELIEF = 'disbelief' 14 | EATING = 'eating' 15 | GRIMACE = 'grimace' 16 | SAD = 'sad' 17 | SCREAM_OPEN = 'scream_open' 18 | SERIOUS = 'serious' 19 | SMILE = 'smile' 20 | TONGUE = 'tongue' 21 | TWINKLE = 'twinkle' 22 | VOMIT = 'vomit' 23 | BIG_SMILE = 'big_smile' 24 | -------------------------------------------------------------------------------- /python_avatars/nose_types.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | 3 | 4 | class NoseType(AvatarPart): 5 | """Nose types""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'nose_types.py' 9 | __path__ = 'avatar_parts/nose' 10 | 11 | DEFAULT = 'default' 12 | SMALL = 'small' 13 | WIDE = 'wide' 14 | -------------------------------------------------------------------------------- /python_avatars/skin_colors.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarColor 2 | 3 | 4 | class SkinColor(AvatarColor): 5 | """Skin colors. You can use any other color using its hex code""" 6 | 7 | __install__ = True 8 | __enum_path__ = 'skin_colors.py' 9 | 10 | TANNED = '#FD9841' 11 | YELLOW = '#F8D25C' 12 | PALE = '#FFDBB4' 13 | LIGHT = '#EDB98A' 14 | BROWN = '#D08B5B' 15 | DARK_BROWN = '#AE5D29' 16 | BLACK = '#614335' 17 | -------------------------------------------------------------------------------- /python_avatars/top_types.py: -------------------------------------------------------------------------------- 1 | from .base_enums import AvatarPart 2 | from .hair_types import HairType 3 | from .hat_types import HatType 4 | 5 | 6 | class TopType(AvatarPart): 7 | """ 8 | Hair/top of head types 9 | """ 10 | __install__ = False 11 | __enum_path__ = 'top_types.py' 12 | __path__ = 'avatar_parts/top' 13 | 14 | @staticmethod 15 | def get_all(): 16 | return list(HairType) + list(HatType) 17 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | from python_avatars import __version__ 4 | 5 | with open('README.md') as readme_file: 6 | README = readme_file.read() 7 | 8 | setup_args = dict( 9 | name='python_avatars', 10 | version=__version__, 11 | description='SVG avatar library for Python', 12 | long_description_content_type="text/markdown", 13 | long_description=README, 14 | license='MIT', 15 | packages=['python_avatars'], 16 | package_dir={ 17 | 'python_avatars': 'python_avatars' 18 | }, 19 | package_data={'python_avatars': [ 20 | '*.json', 21 | 'avatar_parts/**/*.svg', 22 | 'avatar_parts/**/**/*.svg' 23 | ]}, 24 | author='Ibon', 25 | author_email='ibonescartin@gmail.com', 26 | keywords=['avatar', 'svg', 'python', 'face', 'custom'], 27 | url='https://github.com/ibonn/python_avatars', 28 | download_url='https://pypi.org/project/python_avatars/', 29 | project_urls={ 30 | "Documentation": "https://readthedocs.org/projects/python_avatars/", 31 | "Source Code": "https://github.com/ibonn/python_avatars" 32 | }, 33 | classifiers=[ 34 | 'Development Status :: 5 - Production/Stable', 35 | 'Intended Audience :: Developers', 36 | 'License :: OSI Approved :: MIT License', 37 | 'Operating System :: OS Independent', 38 | 'Programming Language :: Python', 39 | 'Programming Language :: Python :: 3', 40 | 'Topic :: Multimedia', 41 | 'Topic :: Multimedia :: Graphics', 42 | 'Topic :: Software Development :: Libraries :: Python Modules' 43 | ], 44 | include_package_data=True 45 | ) 46 | 47 | install_requires = [] 48 | 49 | if __name__ == '__main__': 50 | setup(**setup_args, install_requires=install_requires) 51 | -------------------------------------------------------------------------------- /test/test_avatar.py: -------------------------------------------------------------------------------- 1 | import os 2 | import random 3 | import pytest 4 | 5 | import python_avatars as pa 6 | 7 | 8 | def test_avatar_generation(): 9 | assert pa.Avatar().render("avatar.svg") != "" 10 | assert os.path.isfile("avatar.svg") 11 | 12 | 13 | def test_random_avatar(): 14 | random.seed(123) 15 | 16 | avatar_1 = pa.Avatar.random() 17 | avatar_2 = pa.Avatar.random() 18 | 19 | assert avatar_1 != avatar_2 20 | 21 | 22 | def test_not_installable(): 23 | with pytest.raises(RuntimeError): 24 | pa.install_part("examples/install/suit.svg", pa.TopType) 25 | 26 | 27 | def test_install_installed_part(): 28 | pa.install_part("examples/install/suit.svg", pa.ClothingType) 29 | with pytest.raises(FileExistsError): 30 | pa.install_part("examples/install/suit.svg", pa.ClothingType) 31 | 32 | 33 | def test_cross_install(): 34 | with pytest.raises(RuntimeError): 35 | pa.install_part("examples/install/suit.svg", pa.HairColor) 36 | 37 | 38 | def test_bad_install(): 39 | with pytest.raises(FileNotFoundError): 40 | pa.install_part("this_file_does_not_exist.svg", pa.HairType) 41 | 42 | 43 | def test_invalid_color(): 44 | with pytest.raises(RuntimeError): 45 | pa.install_color("INVALID_1", "#FF00", pa.ClothingColor) 46 | 47 | with pytest.raises(RuntimeError): 48 | pa.install_color("INVALID_2", "#fa08g5", pa.ClothingColor) 49 | 50 | with pytest.raises(RuntimeError): 51 | pa.install_color("INVALID_WHITE", "ffffff", pa.ClothingColor) 52 | -------------------------------------------------------------------------------- /tools/downloader.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | import requests 5 | from bs4 import BeautifulSoup 6 | 7 | print('[*] Connecting to blush.design...') 8 | response = requests.get( 9 | 'https://blush.design/collections/rChdrB8vX8xQJunpDPp8/avatars/avataaar-default/') 10 | 11 | if response.status_code == 200: 12 | print('[+] Connection successful. Parsing page...') 13 | soup = BeautifulSoup(response.text, features='lxml') 14 | avatar_parts = soup.find("script", {"id": "__NEXT_DATA__"}) 15 | print('[+] Avatar parts retrieved. Parsing avatar parts...') 16 | parsed_json = json.loads(avatar_parts.contents[0]) 17 | avatar_parts = parsed_json['props']['pageProps']['initialBlushData']['modificationOptions']['children'] 18 | print(f'[+] {len(avatar_parts)} attributes found') 19 | for attr in avatar_parts: 20 | print(f' * {attr["id"]}') 21 | 22 | print('[*] Starting downloads...') 23 | for elem in avatar_parts: 24 | id_path = f'downloads/{elem["id"]}' 25 | os.makedirs(id_path) 26 | for option in elem['options']: 27 | 28 | print(f'[*] Downloading {elem["id"]}/{option}...') 29 | 30 | url = f'https://cdn.blush.design/collections/rChdrB8vX8xQJunpDPp8/v16/{elem["id"]}/cropped/{option}.svg' 31 | response = requests.get(url) 32 | 33 | if response.status_code == 200: 34 | option = option.replace(' ', '_') 35 | option = option.lower() 36 | 37 | with open(f'{id_path}/{option}.svg', 'w', encoding='utf-8') as f: 38 | f.write(response.text) 39 | else: 40 | print( 41 | f'[!] {elem["id"]}/{option}... download error: {response.status_code}') 42 | print('[+] Finished!') 43 | else: 44 | print(f'[!] Connection error: {response.status_code}') 45 | --------------------------------------------------------------------------------