Ryan M
Ryan M

Reputation: 11

What's the best way to arc/bend a text image?

I'm looking for a way to mimic Photoshop's "arc" transformation that can be applied to text. For example, I want to change this:

Before

to this:

After

Possibilities I've considered are individually rotating, translating, and pasting letters using Pillow in such a manner that an arc is achieved, but this is a bit unwieldy. I see that Pillow also has an Image.transform option, but I'm clueless as to how to configure the options and/or map pixels to achieve the result I'm after.

Anyone know of a good way to do this? Figured I'd ask before going too far down one of the above rabbit holes.

Upvotes: 1

Views: 783

Answers (2)

Sue Donhym
Sue Donhym

Reputation: 121

thanks to fahimnawaz7 for the answer above. I slightly modified this to allow for a transparent background and to do negative angles as well. My first submission to give back to this wonderful community :)

import wand

def curved_text_to_image(
text: str,
font_filepath: str,
font_size: int,
color: str,  #assumes hex string
curve_degree: int):
"""
Uses ImageMagik / wand - so have to ensure its installed.
"""
with wand.image.Image(width=1, height=1, resolution=(600, 600)) as img: # open an image
    with wand.drawing.Drawing() as draw:   # open a drawing objetc
        # assign font details
        draw.font = font_filepath
        draw.font_size = font_size
        draw.fill_color = wand.color.Color(color)
        # get size of text
        metrics = draw.get_font_metrics(img, text)
        height, width = int(metrics.text_height), int(metrics.text_width)
        # resize the image
        img.resize(width=width, height=height)
        # draw the text
        draw.text(0, height, text)
        draw(img)
        img.virtual_pixel = 'transparent'
        # curve_degree arc, rotated 0 degrees - ie at the top
        if curve_degree >= 0:
            img.distort('arc', (curve_degree, 0))
        else:
            # rotate it 180 degrees, then distory and rotate back 180 degrees
            img.rotate(180)
            img.distort('arc', (abs(curve_degree), 180))
        img.format = 'png'
        wand.display.display(img)
return img

Upvotes: 3

fahimnawaz7
fahimnawaz7

Reputation: 35

You can use wand. Here is a sample code.

from wand.image import Image
    
with Image(filename ="img.png") as img: 
    img.distort('arc', (45, )) 
    img.save(filename ='saved_image.png')

Upvotes: 1

Related Questions