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(): try: 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) try: uid = data[‘uid’] file_upload = File(filename=imageName, filetype=’image’, uploader=fetch_user) |
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) |
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) print(“done”) 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:
Resources
- The Pull Request for the same : https://github.com/fossasia/badgeyay/pull/939
- The Issue for the same : https://github.com/fossasia/badgeyay/issues/938
- Read about cairosvg : https://cairosvg.org/
- Read about adding routes Blueprint : http://flask.pocoo.org/docs/1.0/blueprints/
- Link to docs of base64 : https://docs.python.org/2/library/base64.html