Custom Colored Images with Badgeyay

Backend functionality of any Badge generator is to generate badges as per the requirements of the user. Currently Badgeyay is capable of generating badges by the following way:

  • Adding or Selecting a Pre-defined Image from the given set
  • Uploading a new image and then using it as a background

Well, badgeyay has been missing a functionality of generating Custom Colored images.

What is meant by Custom Colored Badges?

Currently, there are a set of 7 different kind of pre-defined images to choose from. But let’s say that a user want to choose from the images but doesn’t like any of the color. Therefore we provide the user with an additional option of applying custom background-color for their badges. This allows Badgeyay to deliver a more versatile amount of badges than ever before.

Adding the functionality to backend

Lets see how this functionality has been implemented in the backend of the project.

Step 1 :  Adding a background-color route to backend

Before generating badges, we need to know that what is the color that the user wants on the badge. Therefore we created a route that gathers the color and saves the user-defined.svg into that particular color.

@router.route(‘/background_color’, methods=[‘POST’])
def background_color():
data = request.get_json()[‘data’][‘attributes’]
bg_color = data[‘bg_color’]
except Exception:
return ErrorResponse(PayloadNotFound().message, 422, {‘Content-Type’: ‘application/json’}).respond()

svg2png = SVG2PNG()

bg_color = ‘#’ + str(bg_color)
user_defined_path = svg2png.do_svg2png(1, bg_color)
with open(user_defined_path, “rb”) as image_file:
image_data = base64.b64encode(

imageName = saveToImage(imageFile=image_data.decode(‘utf-8’), extension=”.png”)
except Exception:
return ErrorResponse(ImageNotFound().message, 422, {‘Content-Type’: ‘application/json’}).respond()

uid = data[‘uid’]
fetch_user = User.getUser(user_id=uid)
if fetch_user is None:
return ErrorResponse(UserNotFound(uid).message, 422, {‘Content-Type’: ‘application/json’}).respond()

file_upload = File(filename=imageName, filetype=’image’, uploader=fetch_user)
return jsonify(ColorImageSchema().dump(file_upload).data)

Step 2: Adding Schema for background-color to backend

To get and save values from and to database, we need to have some layer of abstraction and so we use schemas created using marshmallow_jsonapi

class ColorImageSchema(Schema):
class Meta:
type_ = ‘bg-color’
self_view = ‘fileUploader.background_color’
kwargs = {‘id’: ‘<id>’}

id = fields.Str(required=True, dump_only=True)
filename = fields.Str(required=True)
filetype = fields.Str(required=True)
user_id = fields.Relationship(
self_url_kwargs={‘file_id’: ‘<id>’},
related_url_kwargs={‘id’: ‘<id>’},

Now we have our schema and route done, So we can move forward with the logic of making badges.

Step 3 : Converting the SVG to PNG and adding custom color

Now we have the user-defined color for the badge background, but we still need a way to apply it to the badges. It is done using the following code below.

def do_svg2png(self, opacity, fill):
Module to convert svg to png
:param `opacity` – Opacity for the output
:param `fill` –  Background fill for the output
filename = os.path.join(self.APP_ROOT, ‘svg’, ‘user_defined.svg’)
tree = parse(open(filename, ‘r’))
element = tree.getroot()
# changing style using XPath.
path = element.xpath(‘//*[@id=”rect4504″]’)[0]
style_detail = path.get(“style”)
style_detail = style_detail.split(“;”)
style_detail[0] = “opacity:” + str(opacity)
style_detail[1] = “fill:” + str(fill)
style_detail = ‘;’.join(style_detail)
path.set(“style”, style_detail)
# changing text using XPath.
path = element.xpath(‘//*[@id=”tspan932″]’)[0]
# Saving in the original XML tree
etree.ElementTree(element).write(filename, pretty_print=True)
png_name = os.path.join(self.APP_ROOT, ‘static’, ‘uploads’, ‘image’, str(uuid.uuid4())) + “.png”
svg2png(url=filename, write_to=png_name)
return png_name

Finally , we have our badges generating with custom colored background.

Here is a sample image:



Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.