user17493432
user17493432

Reputation: 11

How would I warp text around an image's edges?

I am trying to create an image with the edges replaced with text, similar to This Youtube video thumbnail but from a source image. I've used OpenCV to get a version of a source image with edges, and Pillow to actually write the text, but I'm not sure where to start when it comes to actually manipulating the text automatically to fit to the edges. The code I have so far is:

import cv2 as cv
from matplotlib import pyplot as plt
from PIL import Image, ImageFont, ImageDraw, ImageShow

font = ImageFont.truetype(r"C:\Users\X\Downloads\Montserrat\Montserrat-Light.ttf", 12)
text = ["text", "other text"]

img = cv.imread(r"C:\Users\X\Pictures\picture.jpg",0)
edges = cv.Canny(img,100,200)

img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
im_pil = Image.fromarray(edges)

This code is just for the edge detection and moving the detected edges to Pillow.

Please help

Upvotes: 0

Views: 664

Answers (2)

fmw42
fmw42

Reputation: 53164

I am not sure where the "edges" comes in from the canny edge detector.

However, the circular text wrap can be done very simply in Python/Wand that uses ImageMagick. Or one can do that in Python/OpenCV using cv2.remap and custom transformation maps.

Input:

enter image description here

1. Python Wand

(output size determined automatically from input size)

from wand.image import Image
from wand.font import Font
from wand.display import display

with Image(filename='some_text.png') as img:
    img.background_color = 'white'
    img.virtual_pixel = 'white'
    # 360 degree arc, rotated 0 degrees
    img.distort('arc', (360,0))
    img.save(filename='some_text_arc.png')
    img.format = 'png'
    display(img)

Result:

enter image description here

2. Python/OpenCV

import numpy as np
import cv2
import math

# read input
img = cv2.imread("some_text.png")
hin, win = img.shape[:2]
win2 = win / 2

# specify desired square output dimensions and center
hout = 100
wout = 100
xcent = wout / 2
ycent = hout / 2
hwout = max(hout,wout)
hwout2 = hwout / 2

# set up the x and y maps as float32
map_x = np.zeros((hout, wout), np.float32)
map_y = np.zeros((hout, wout), np.float32)

# create map with the arc distortion formula --- angle and radius
for y in range(hout):
    Y = (y - ycent)
    for x in range(wout):
        X = (x - xcent)
        XX = (math.atan2(Y,X)+math.pi/2)/(2*math.pi)
        XX = XX - int(XX+0.5)
        XX = XX * win + win2
        map_x[y, x] = XX
        map_y[y, x] = hwout2 - math.hypot(X,Y)

# do the remap  this is where the magic happens
result = cv2.remap(img, map_x, map_y, cv2.INTER_CUBIC, borderMode = cv2.BORDER_CONSTANT, borderValue=(255,255,255))

# save results
cv2.imwrite("some_text_arc.jpg", result)

# display images
cv2.imshow('img', img)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Result:

enter image description here

Upvotes: 2

Tim Roberts
Tim Roberts

Reputation: 54812

Neither OpenCV nor PIL has a way to do that, but you can use ImageMagick. How to warp an image to take shape of path with python?

Upvotes: 0

Related Questions