diff --git a/twobuntu/touch/forms.py b/twobuntu/touch/forms.py index ca2109a..68b8c04 100644 --- a/twobuntu/touch/forms.py +++ b/twobuntu/touch/forms.py @@ -1,10 +1,15 @@ from django import forms +from twobuntu.touch.generator import TEMPLATES + class DeviceArtForm(forms.Form): """ - Form for uploading an app screenshot. + Form for uploading an app image. """ + template = forms.TypedChoiceField( + choices=[(i, t['title']) for i, t in enumerate(TEMPLATES)], + coerce=int, + ) image = forms.ImageField() - add_panel = forms.BooleanField(required=False, label='Add the Unity panel to the picture') diff --git a/twobuntu/touch/generator.py b/twobuntu/touch/generator.py new file mode 100644 index 0000000..35e2cf1 --- /dev/null +++ b/twobuntu/touch/generator.py @@ -0,0 +1,50 @@ +from io import BytesIO +from math import ceil + +from django.contrib.staticfiles import finders +from PIL import Image + +# Coordinates for rendering the picture with and without the Unity panel +# Each item in the array represents a layer for the generator to render +# The format of the tuple is (filename, dest_x, dest_y, dest_w, dest_h) +TEMPLATES = [ + { + 'title': 'Meizu MX3 with Unity Panel', + 'dimensions': (1346, 2313), + 'layers': [ + (None, 131, 286, 1080, 1727), + ('panel.png', 131, 213, 1080, 73), + ('mx3.png', 0, 0, 1346, 2313), + ], + }, + { + 'title': 'Meizu MX3 without Unity Panel', + 'dimensions': (1346, 2313), + 'layers': [ + (None, 131, 213, 1080, 1800), + ('mx3.png', 0, 0, 1346, 2313), + ], + }, +] + + +def generate_device_art(template, image): + """ + Combine the layers for the template into a final image. + """ + # Create the final image upon which everything will be rendered + t = TEMPLATES[template] + o = Image.new('RGBA', t['dimensions']) + # For each of the layers, resize and crop according to the definition, and blend + for l in t['layers']: + i = Image.open(finders.find('img/touch/%s' % l[0]) if l[0] else image) + w, h = i.size + i = i.crop((0, 0, w, int(ceil(float(l[4]) / float(l[3]) * w)))) + i = i.resize((l[3], l[4]), Image.ANTIALIAS) + c = Image.new('RGBA', t['dimensions']) + c.paste(i, (l[1], l[2])) + o = Image.alpha_composite(o, c) + # Return a file-like object representing the rendered picture + response = BytesIO() + o.save(response, format='PNG') + return response.getvalue() diff --git a/twobuntu/touch/static/img/touch-preview.png b/twobuntu/touch/static/img/touch-preview.png deleted file mode 100644 index e21bab0..0000000 Binary files a/twobuntu/touch/static/img/touch-preview.png and /dev/null differ diff --git a/twobuntu/touch/static/img/touch/mx3-preview.png b/twobuntu/touch/static/img/touch/mx3-preview.png new file mode 100644 index 0000000..ec2ff93 Binary files /dev/null and b/twobuntu/touch/static/img/touch/mx3-preview.png differ diff --git a/twobuntu/touch/static/img/touch-frame.png b/twobuntu/touch/static/img/touch/mx3.png similarity index 100% rename from twobuntu/touch/static/img/touch-frame.png rename to twobuntu/touch/static/img/touch/mx3.png diff --git a/twobuntu/touch/static/img/touch-panel.png b/twobuntu/touch/static/img/touch/panel.png similarity index 100% rename from twobuntu/touch/static/img/touch-panel.png rename to twobuntu/touch/static/img/touch/panel.png diff --git a/twobuntu/touch/templates/touch/generator.html b/twobuntu/touch/templates/touch/generator.html index 94f8a12..9984ab4 100644 --- a/twobuntu/touch/templates/touch/generator.html +++ b/twobuntu/touch/templates/touch/generator.html @@ -4,7 +4,7 @@ {% block content %}
- +

Ubuntu Touch Device Art Generator

@@ -25,17 +25,21 @@

Ubuntu Touch Device Art Generator

Our tool will automatically resize and crop the image if necessary.


-
- {% csrf_token %} - {% for field in form %} - {% include "fragments/field.html" %} - {% endfor %} -
- -
+
+
+
+ {% csrf_token %} + {% for field in form %} + {% include "fragments/field.html" %} + {% endfor %} +
+ +
+
+
{% endblock %} diff --git a/twobuntu/touch/views.py b/twobuntu/touch/views.py index f422622..5f39502 100644 --- a/twobuntu/touch/views.py +++ b/twobuntu/touch/views.py @@ -1,55 +1,18 @@ -from django.contrib.staticfiles import finders from django.http import HttpResponse from django.shortcuts import render -from io import BytesIO -from PIL import Image from twobuntu.touch.forms import DeviceArtForm - -# Dimensions used for calculations -TEMPLATE_W = 1346 -TEMPLATE_H = 2313 -SCREENSHOT_X = 131 -SCREENSHOT_Y = 213 -SCREENSHOT_W = 1080 -SCREENSHOT_H = 1800 -PANEL_H = 73 - - -def generate_device_art(screenshot, add_panel=True): - """ - Load the template & overlay and combine them with the screenshot. - """ - response = BytesIO() - # Open the two images to be combined - s = Image.open(screenshot) - t = Image.open(finders.find('img/touch-frame.png')) - # Crop and resize the screenshot - w, h = s.size - s = s.crop((0, 0, w, int(float(SCREENSHOT_H) / float(SCREENSHOT_W) * w))) - s = s.resize((SCREENSHOT_W, SCREENSHOT_H), Image.ANTIALIAS) - # Create the output image for pasting the screenshot onto - o = Image.new('RGBA', (TEMPLATE_W, TEMPLATE_H)) - # Add the panel if requested - if add_panel: - p = Image.open(finders.find('img/touch-panel.png')) - o.paste(p, (SCREENSHOT_X, SCREENSHOT_Y)) - o.paste(s, (SCREENSHOT_X, SCREENSHOT_Y + PANEL_H)) - else: - o.paste(s, (SCREENSHOT_X, SCREENSHOT_Y)) - # Blend the frame above and save the image to the BytesIO - Image.alpha_composite(o, t).save(response, format='PNG') - return response.getvalue() +from twobuntu.touch.generator import generate_device_art def generator(request): """ - Generate a picture of a device with a screenshot. + Generate a picture of a device with a user-supplied image. """ if request.method == 'POST': form = DeviceArtForm(data=request.POST, files=request.FILES) if form.is_valid(): - image = generate_device_art(request.FILES['image'], form.cleaned_data['add_panel']) + image = generate_device_art(form.cleaned_data['template'], request.FILES['image']) response = HttpResponse(image, content_type='image/png') response['Content-Disposition'] = 'attachment; filename="ubuntu-touch-device-art.png"' response['Content-Length'] = len(image)