skip to Main Content

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.

2

Answers


  1. 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')
    
    Login or Signup to reply.
  2. 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
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search