Update badge rendering to reflect actual render

* Switch to showing the PNG version by default, as this reflects what
  will actually be rendered and sent to the printer
* Include the greyscale filter
* Include the twemoji font we'll use for rendering the badges
This commit is contained in:
James Polley 2018-01-15 00:10:16 +11:00
parent 653cd80891
commit 39669055ef
3 changed files with 32 additions and 12 deletions

View file

@ -12,6 +12,9 @@
--> -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 1749 1241" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-miterlimit:10;"> <svg width="100%" height="100%" viewBox="0 0 1749 1241" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-miterlimit:10;">
<filter id="grayscale">
<feColorMatrix type="saturate" values="0"/>
</filter>
<g transform="matrix(1.15527,0,0,1.15527,-22.9233,770.581)"> <g transform="matrix(1.15527,0,0,1.15527,-22.9233,770.581)">
<g transform="matrix(1,0,0,1,358.181,164.105)"> <g transform="matrix(1,0,0,1,358.181,164.105)">
<path d="M0,24.414L0,18.184L3.151,15.141C6.52,11.845 8.44,10.323 8.44,8.44C8.44,7.136 7.824,6.991 5.615,6.991C3.296,6.991 0.435,7.534 0.435,7.534L0.072,1.34C0.072,1.34 3.84,0 7.933,0C13.366,0 16.735,2.463 16.735,7.244C16.735,11.41 15.54,13.438 11.591,16.191L9.164,17.894L16.59,17.894L16.59,24.414L0,24.414Z" style="fill:rgb(78,135,160);fill-rule:nonzero;"/> <path d="M0,24.414L0,18.184L3.151,15.141C6.52,11.845 8.44,10.323 8.44,8.44C8.44,7.136 7.824,6.991 5.615,6.991C3.296,6.991 0.435,7.534 0.435,7.534L0.072,1.34C0.072,1.34 3.84,0 7.933,0C13.366,0 16.735,2.463 16.735,7.244C16.735,11.41 15.54,13.438 11.591,16.191L9.164,17.894L16.59,17.894L16.59,24.414L0,24.414Z" style="fill:rgb(78,135,160);fill-rule:nonzero;"/>
@ -1020,16 +1023,16 @@
</g> </g>
<g transform="matrix(0.876643,0,0,0.876643,62.2881,185.276)"> <g transform="matrix(0.876643,0,0,0.876643,62.2881,185.276)">
<g transform="matrix(0.607846,0,0,0.607922,138.923,372.07)"> <g transform="matrix(0.607846,0,0,0.607922,138.923,372.07)">
<text x="0px" y="0px" style="font-family:'Roboto-Regular', 'Roboto';font-size:144.577px;">{{ user.attendee.attendeeprofilebase.attendeeprofile.name }}</text> <text x="0px" y="0px" filter="url(#grayscale)" style="font-family:'Roboto-Regular', 'Roboto', 'Twitter Color Emoji';font-size:144.577px;">{{ user.attendee.attendeeprofilebase.attendeeprofile.name }}</text>
</g> </g>
<g transform="matrix(0.607846,0,0,0.607922,138.923,449.05)"> <g transform="matrix(0.607846,0,0,0.607922,138.923,449.05)">
<text x="0px" y="0px" style="font-family:'Roboto-Regular', 'Roboto';font-size:96.385px;">{{ user.attendee.attendeeprofilebase.attendeeprofile.company }}</text> <text x="0px" y="0px" filter="url(#grayscale)" style="font-family:'Roboto-Regular', 'Roboto', 'Twitter Color Emoji';font-size:96.385px;">{{ user.attendee.attendeeprofilebase.attendeeprofile.company }}</text>
</g> </g>
<g transform="matrix(0.607846,0,0,0.607922,140.5,504.582)"> <g transform="matrix(0.607846,0,0,0.607922,140.5,504.582)">
<text x="0px" y="0px" style="font-family:'Roboto-Regular', 'Roboto';font-size:60.24px;">{{ user.attendee.attendeeprofilebase.attendeeprofile.free_text_1 }}</text> <text x="0px" y="0px" filter="url(#grayscale)" style="font-family:'Roboto-Regular', 'Roboto', 'Twitter Color Emoji';font-size:60.24px;">{{ user.attendee.attendeeprofilebase.attendeeprofile.free_text_1 }}</text>
</g> </g>
<g transform="matrix(0.607846,0,0,0.607922,140.5,550.359)"> <g transform="matrix(0.607846,0,0,0.607922,140.5,550.359)">
<text x="0px" y="0px" style="font-family:'Roboto-Regular', 'Roboto';font-size:60.24px;">{{ user.attendee.attendeeprofilebase.attendeeprofile.free_text_2 }}</text> <text x="0px" y="0px" filter="url(#grayscale)" style="font-family:'Roboto-Regular', 'Roboto', 'Twitter Color Emoji';font-size:60.24px;">{{ user.attendee.attendeeprofilebase.attendeeprofile.free_text_2 }}</text>
</g> </g>
<g transform="matrix(0.999321,0,0,0.999446,0,-507.874)"> <g transform="matrix(0.999321,0,0,0.999446,0,-507.874)">
<g id="text23417" transform="matrix(1,0,0,1,353.552,780.612)"> <g id="text23417" transform="matrix(1,0,0,1,353.552,780.612)">

Before

Width:  |  Height:  |  Size: 403 KiB

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

View file

@ -2,6 +2,7 @@ import datetime
import zipfile import zipfile
import os import os
import logging import logging
import subprocess
from django.contrib import messages from django.contrib import messages
@ -38,7 +39,6 @@ from django.template import Context, Template, loader
from lxml import etree from lxml import etree
from copy import deepcopy from copy import deepcopy
from cairosvg import svg2pdf, svg2png
from registrasion.forms import BadgeForm, ticket_selection from registrasion.forms import BadgeForm, ticket_selection
from registrasion.contrib.badger import ( from registrasion.contrib.badger import (
@ -57,7 +57,6 @@ _GuidedRegistrationSection = namedtuple(
) )
) )
@util.all_arguments_optional @util.all_arguments_optional
class GuidedRegistrationSection(_GuidedRegistrationSection): class GuidedRegistrationSection(_GuidedRegistrationSection):
''' Represents a section of a guided registration page. ''' Represents a section of a guided registration page.
@ -1115,26 +1114,44 @@ def _get_badge_template_name():
return os.path.join(settings.PROJECT_ROOT, 'pinaxcon', 'templates', return os.path.join(settings.PROJECT_ROOT, 'pinaxcon', 'templates',
settings.BADGER_DEFAULT_SVG) settings.BADGER_DEFAULT_SVG)
@login_required @login_required
def user_badge(request, format="svg"): def user_badge(request, format="png"):
'''Shows the logged-in user their badge''' '''Shows the logged-in user their badge'''
return render_badge(request.user, format) return render_badge(request.user, format)
@user_passes_test(_staff_only) @user_passes_test(_staff_only)
def badge(request, user_id, format="svg"): def badge(request, user_id, format="png"):
''' Renders a single user's badge (SVG). ''' ''' Renders a single user's badge (PNG). '''
user_id = int(user_id) user_id = int(user_id)
user = User.objects.get(pk=user_id) user = User.objects.get(pk=user_id)
return render_badge(user, format) return render_badge(user, format)
def render_badge(user, format="svg"): def _convert_img(img, outformat="png",dpi=200,width=None):
if hasattr(img, "encode"): #a string, or a SafeText
img=img.encode()
width = width or dpi*5.83 #5.83 inches in A6 portrait
conversion_cmdline = [
"convert",
"-density",str(dpi),
"-resize",str(width),
]
if outformat=="png":
conversion_cmdline.extend(["-background","white",
"-flatten"])
conversion_cmdline.extend(["-", "{}:-".format(outformat)])
out = subprocess.run(conversion_cmdline,
input=img,
stdout=subprocess.PIPE).stdout
return out
def render_badge(user, format="png"):
rendered = render_badge_svg(user) rendered = render_badge_svg(user)
if format == "png": if format == "png":
rendered = svg2png(bytestring=rendered, dpi=72, scale=3) rendered = _convert_img(rendered, outformat="png")
elif format == "pdf": elif format == "pdf":
rendered = svg2pdf(bytestring=rendered, dpi=72, scale=3) rendered = _convert_img(rendered, outformat="pdf")
response = HttpResponse(rendered) response = HttpResponse(rendered)