pythonwand

How can I use pango (HTML subset) with the ImageMagick Python library wand?


My goal is to take a picture and add a centered text to its center. I want to use italics and bold for this text, specified with the HTML-like pango.

I currently have this code:

import os
from wand.image import Image
from wand.drawing import Drawing
from wand.color import Color

with Image(filename='testimg.png') as img:
    with Drawing() as draw:
        draw.font = 'Arial'
        draw.font_size = 36
        text = 'pango:<b>Formatted</b> text'
        (width, height) = draw.get_font_metrics(img, text).size()
        print(width, height)
        x = int((img.width - width) / 2)
        
        y = int((img.height - height) / 2)
        draw.fill_color = Color('black')
        draw.text(x, y, text)
        draw(img)
    img.save(filename='output.jpg')

However, the text does not get formatted currently, but is simply "pango:Formatted text", and it is very hard to find any documentation. (Before this approach I tried using pillow, but that does not seem to support anything HTML-like at all)


Solution

  • It kind of works if you create a new image and set the file path to a pango string:

    import os
    from wand.image import Image
    from wand.drawing import Drawing
    from wand.color import Color
    
    # Open the image file
    with Image(filename='testimg.png') as img:
        # Create a Drawing object
        with Image(filename="pango:<b>Formatted</b> text") as text_img:
    
            text_img.transparent_color('white', alpha=0, fuzz=0)
            text_img.font_path = r"Montserrat-SemiBold.ttf"
            text_img.font_size = 36
            # Calculate the x and y coordinates to center the text on the image
            x = int((img.width - text_img.width) / 2)
            y = int((img.height - text_img.height) / 2)
    
            # Draw the text on the image
            img.composite(text_img, left=x, top=y)
    
        # Save the image
        img.save(filename='outputnew.jpg')
    

    However, the result is very ugly because the text rendering is like on a white background, only that the background is not white: Example pic