Now it only output the final img with ‘yes’ on it.
But i do want to add all pictures into one single image.
This is a black-white image, generated with font.
enter image description here
prompt: text_testnyes, it’s just for test
texts = str(prompt).split('n')
n_lines = len(texts)
if len(texts ) == 0:
texts = [' ']
max_chars = 20
font_path = os.path.join(folder_paths.models_dir, "fonts", font)
self.font = ImageFont.truetype(font_path, size=60, encoding='utf-8')
mask_img = tensor2numpy_cv2(pos_mask)
mask_img = cv2.cvtColor(mask_img, cv2.COLOR_GRAY2RGB) # cv2二值图(mask)转rgb
mask_img = cv2.bitwise_not(mask_img) # cv2图片取反
from .AnyText_scripts.AnyText_pipeline_util import resize_image
from .AnyText_scripts.AnyText_t3_dataset import draw_glyph2
from .AnyText_scripts.AnyText_pipeline import separate_pos_imgs, find_polygon
draw_pos = resize_image(mask_img, max_length=768)
draw_pos = cv2.resize(draw_pos, (width, height))
pos_imgs = 255-draw_pos
pos_imgs = pos_imgs[..., 0:1]
pos_imgs = cv2.convertScaleAbs(pos_imgs)
_, pos_imgs = cv2.threshold(pos_imgs, 254, 255, cv2.THRESH_BINARY)
pos_imgs = separate_pos_imgs(pos_imgs, sort_radio)
if len(pos_imgs) == 0:
pos_imgs = [np.zeros((height, width, 1))]
if len(pos_imgs) < n_lines:
if n_lines == 1 and texts[0] == ' ':
# pass # text-to-image without text
print('33[93m', f'Warning: text-to-image without text.', '33[0m')
else:
# return None, -1, f'Found {len(pos_imgs)} positions that < needed {n_lines} from prompt, check and try again!', ''
raise ValueError(f'Found {len(pos_imgs)} positions that < needed {n_lines} from prompt, check and try again(手绘遮罩数少于要绘制的文本数,检查再重试)!')
elif len(pos_imgs) > n_lines:
print('33[93m', f'Warning: found {len(pos_imgs)} positions that > needed {n_lines} from prompt.', '33[0m')
pre_pos = []
poly_list = []
for input_pos in pos_imgs:
if input_pos.mean() != 0:
input_pos = input_pos[..., np.newaxis] if len(input_pos.shape) == 2 else input_pos
poly, pos_img = find_polygon(input_pos)
pre_pos += [pos_img/255.]
poly_list += [poly]
else:
pre_pos += [np.zeros((height, width, 1))]
poly_list += [None]
for i in range(len(texts)):
text = texts[i]
if len(text) > max_chars:
text = text[:max_chars]
gly_scale = 2
if pre_pos[i].mean() != 0:
_, glyphs = draw_glyph2(self.font, text, poly_list[i], scale=gly_scale, width=width, height=height, add_space=False)
font_img = pil2tensor(glyphs)
return (font_img, )
def draw_glyph2(font, text, polygon, vertAng=10, scale=1, width=512, height=512, add_space=True):
enlarge_polygon = polygon*scale
rect = cv2.minAreaRect(enlarge_polygon)
box = cv2.boxPoints(rect)
box = np.int0(box)
w, h = rect[1]
angle = rect[2]
if angle < -45:
angle += 90
angle = -angle
if w < h:
angle += 90
vert = False
if (abs(angle) % 90 < vertAng or abs(90-abs(angle) % 90) % 90 < vertAng):
_w = max(box[:, 0]) - min(box[:, 0])
_h = max(box[:, 1]) - min(box[:, 1])
if _h >= _w:
vert = True
angle = 0
img = np.zeros((height*scale, width*scale, 3), np.uint8)
img = Image.fromarray(img)
# infer font size
image4ratio = Image.new("RGB", img.size, "white")
draw = ImageDraw.Draw(image4ratio)
_, _, _tw, _th = draw.textbbox(xy=(0, 0), text=text, font=font)
text_w = min(w, h) * (_tw / _th)
if text_w <= max(w, h):
# add space
if len(text) > 1 and not vert and add_space:
for i in range(1, 100):
text_space = insert_spaces(text, i)
_, _, _tw2, _th2 = draw.textbbox(xy=(0, 0), text=text_space, font=font)
if min(w, h) * (_tw2 / _th2) > max(w, h):
break
text = insert_spaces(text, i-1)
font_size = min(w, h)*0.80
else:
shrink = 0.75 if vert else 0.85
font_size = min(w, h) / (text_w/max(w, h)) * shrink
# print('33[93m', font_size, 'n', type(font_size), '33[0m')
if not font_size > 0:
font_size = min(max(1, int(font_size)), 100) #可以防止报错:font size must be greater than 0
new_font = font.font_variant(size=int(font_size))
left, top, right, bottom = new_font.getbbox(text)
text_width = right-left
text_height = bottom - top
layer = Image.new('RGBA', img.size, (0, 0, 0, 0))
draw = ImageDraw.Draw(layer)
if not vert:
draw.text((rect[0][0]-text_width//2, rect[0][1]-text_height//2-top), text, font=new_font, fill=(255, 255, 255, 255))
else:
x_s = min(box[:, 0]) + _w//2 - text_height//2
y_s = min(box[:, 1])
for c in text:
draw.text((x_s, y_s), c, font=new_font, fill=(255, 255, 255, 255))
_, _t, _, _b = new_font.getbbox(c)
y_s += _b
rotated_layer = layer.rotate(angle, expand=1, center=(rect[0][0], rect[0][1]))
x_offset = int((img.width - rotated_layer.width) / 2)
y_offset = int((img.height - rotated_layer.height) / 2)
img.paste(rotated_layer, (x_offset, y_offset), rotated_layer)
cv2_img = img
img = np.expand_dims(np.array(img.convert('1')), axis=2).astype(np.float64)
return (img, cv2_img, )
Tried for loop but i’m not good at it, failed.
Just one step for all text in one image.
New contributor
m zhao is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.