diff --git a/ivatar/tools/forms.py b/ivatar/tools/forms.py index e136f82..84e603e 100644 --- a/ivatar/tools/forms.py +++ b/ivatar/tools/forms.py @@ -69,6 +69,7 @@ class CheckForm(forms.Form): ('monsterid', _('Monster style')), ('identicon', _('Identicon style')), ('mm', _('Mystery man')), + ('mmng', _('Mystery man NextGen')), ('none', _('None')), ], ) diff --git a/ivatar/utils.py b/ivatar/utils.py index 877412d..ae4c8f4 100644 --- a/ivatar/utils.py +++ b/ivatar/utils.py @@ -3,6 +3,7 @@ Simple module providing reusable random_string function ''' import random import string +from PIL import Image, ImageDraw def random_string(length=10): @@ -33,3 +34,58 @@ def openid_variations(openid): var2 = openid.replace('http://', 'https://') var3 = var2[0:-1] return (openid, var1, var2, var3) + +def mm_ng(hash, size=80, add_red=0, add_green=0, add_blue=0): + ''' + Return an MM (mystery man) image, based on a given hash + add some red, green or blue, if specified + ''' + + # Make sure the lightest bg color we paint is e0, else + # we do not see the MM any more + if hash[0] == 'f': hash = 'e0' + + # How large is the circle? + circlesize = size*0.6 + + # Coordinates for the circle + start_x = int(size*0.2) + end_x = start_x+circlesize + start_y = int(size*0.05) + end_y = start_y+circlesize + + # All are the same, based on the input hash + # this should always result in a "gray-ish" background + red = hash[0:2] + green = hash[0:2] + blue = hash[0:2] + + # Add some red (i/a) and make sure it's not over 255 + red = hex(int(red, 16)+add_red).replace('0x', '') + if int(red, 16)>255: red='ff' + + # Add some green (i/a) and make sure it's not over 255 + green = hex(int(green, 16)+add_green).replace('0x', '') + if int(green, 16)>255: green='ff' + + # Add some blue (i/a) and make sure it's not over 255 + blue = hex(int(blue, 16)+add_blue).replace('0x', '') + if int(blue, 16)>255: blue='ff' + + # Assemable the bg color "string" in webnotation. Eg. '#d3d3d3' + bg_color = '#' + red + green + blue + + # Image + image = Image.new('RGB', (size, size)) + draw = ImageDraw.Draw(image) + + # Draw background + draw.rectangle(((0,0), (size, size)), fill=bg_color) + + # Draw MMs head + draw.ellipse((start_x, start_y, end_x, end_y), fill='white') + + # Draw MMs 'body' + draw.polygon(((start_x+circlesize/2, size/2.5), (size*0.15, size), (size-size*0.15, size)), fill='white') + + return image diff --git a/ivatar/views.py b/ivatar/views.py index a206bfc..4c97939 100644 --- a/ivatar/views.py +++ b/ivatar/views.py @@ -27,6 +27,7 @@ from ivatar.settings import AVATAR_MAX_SIZE, JPEG_QUALITY, DEFAULT_AVATAR_SIZE, from ivatar.settings import CACHE_IMAGES_MAX_AGE from . ivataraccount.models import ConfirmedEmail, ConfirmedOpenId from . ivataraccount.models import pil_format, file_format +from . utils import mm_ng URL_TIMEOUT = 5 # in seconds @@ -246,6 +247,18 @@ class AvatarImageView(TemplateView): response['Cache-Control'] = 'max-age=%i' % CACHE_IMAGES_MAX_AGE return response + if str(default) == 'mmng': + mmngimg = mm_ng(hash=kwargs['digest'], size=size) + data = BytesIO() + mmngimg.save(data, 'PNG', quality=JPEG_QUALITY) + data.seek(0) + response = CachingHttpResponse( + uri, + data, + content_type='image/png') + response['Cache-Control'] = 'max-age=%i' % CACHE_IMAGES_MAX_AGE + return response + if str(default) == 'mm' or str(default) == 'mp': # If mm is explicitly given, we need to catch that static_img = path.join('static', 'img', 'mm', '%s%s' % (str(size), '.png'))