`from PIL import Image, ImageDraw, ImageFont
image = Image.new('RGB', (950, 250), color=(255, 255, 255))
TEXT = 'You are a wondeful \033[32mperson.'
font_size = 50
font_type = "SourceCodePro-Bold.ttf"
draw = ImageDraw.Draw(im=image)
font = ImageFont.truetype(font_type, font_size)
draw.multiline_text((int(950 / 2), int(250 / 2)), text=TEXT, font=font,fill=(0, 0, 0), anchor='mm')
image.show()`
I tried to print text on an image using some escape sequence "\033[32m" using PIL (Pillow).
I was expecting the below output image
What I want
What I'm getting
So anybody have any idea that how to get the desired result then it'll be very helpful.
Thanks.
You can try this one and change the position of text. i think this logic will help you. thanks
from PIL import Image, ImageDraw, ImageFont
image = Image.new('RGB', (950, 250), "white")
text1 = "You are a wondeful"
text2="Person"
font_size = 100
font_type = "SourceCodePro-Bold.ttf"
draw = ImageDraw.Draw(im=image)
font = ImageFont.load_default()
draw.multiline_text((int(950 / 2), int(250 / 2)), text=text1, font=font,fill ="black",anchor='mm')
draw.multiline_text((int(1180 / 2), int(250 / 2)), text=text2, font=font,fill = "green",anchor='mm')
image.show()
Related
Faced such a problem. The image is created and saved, everything is correct, but I can't print it automatically. What could be the problem?
P.S. I tried to save the file in PDF format, it is printed automatically, but on the entire A4 sheet, but I need it without changing the scale.
My code:
import win32api
from PIL import Image, ImageDraw, ImageFont
img = Image.new("RGB", (300, 250), 'white')
draw = ImageDraw.Draw(img)
sticker_text = 'Name\nSurname\n\nCompany'
font = ImageFont.truetype('arial.ttf', size=40)
_, _, w, h = draw.textbbox((0, 0), sticker_text, font=font)
draw.text(((300 - w) / 2, (250 - h) / 2), sticker_text, font=font, fill='black', align='center')
img.save('link_to_file.jpg')
file = "link_to_file.jpg"
win32api.ShellExecute(0, "print", file, None, ".", 0)
Thanks for your answers.
from PIL import Image, ImageDraw, ImageFont
import os
img = Image.new('RGB', (100, 30), color = (73, 109, 137))
#fnt = ImageFont.truetype('/Library/Fonts/Arial.ttf', 15)
d = ImageDraw.Draw(img)
d.text((10,10), "Hello world", fill=(255, 255, 0))
#img.save('pil_text_font.png')
I want to print this image on paper. How can I do that?
I tried,
os.startfile(img,'print')
Error:
TypeError: startfile: filepath should be string, bytes or os.PathLike, not Image
Save your image to a file then output to screen like so:
from PIL import Image, ImageDraw, ImageFont
img = Image.new('RGB', (100, 30), color = (73, 109, 137))
#fnt = ImageFont.truetype('/Library/Fonts/Arial.ttf', 15)
d = ImageDraw.Draw(img)
d.text((10,10), "Hello world", fill=(255, 255, 0))
img.save('pil_text_font.png')
# open method used to open different extension image file
im = Image.open(r"pil_text_font.png")
# This method will show image in any image viewer
im.show()
#delete the file immediately after to save space
os.remove("pil_text_font.png")
Here is a link on where I got my information from for this answer: https://www.geeksforgeeks.org/python-pil-image-open-method/
I have a folder with .ttf and .otf fonts and would like to write them on my ImageDraw object but with NO shading. A single RGB only. I have tried bitmap fonts but they A) don't look nice and B) use more than one color anyway.
I have read that there is a library for converting .bdf to .pil. If I convert arial.ttf to arial.bdf and then to arial.pil, will this be what I'm looking for? The text will almost always be dropped onto a background--so should I consider writing the text first on a blank canvas, do a color reduction, and then paste that canvas onto my background?
I have previously made this program using Java and it writes text very nicely on my bitmaps. One color, symmetrical, etc. Image below.
Below are the two attempts with python. The blockier one is a bitmap font, the other is regular arial.ttf.
Here is my code:
def personalize(self):
names = self.personalize_entry.get("1.0", 'end-1c').split('\n')
num_names = len(names)
num_grids = math.ceil(num_names/20)
answer = ask_grid_background()
separator = Image.new('RGB', (473, 1), color_dict['P'])
background = Image.new('RGB', (473, 821), color_dict['.'])
if answer:
showinfo("Bitmap", "Give me the design.")
file_path = filedialog.askopenfilename()
filename = path_leaf(file_path)
filename = filename[:-4]
__, __, center = read(file_path)
if center == 0:
messagebox.showinfo("Hmmm", f"I couldn't find a center...are you sure this is a basic set up?")
return False
img = Image.open(file_path)
size_num = img.size
section = img.crop((5, (size_num[1] - 55 - center), 478, (size_num[1] - center - 15)))
background.paste(separator, (0, 0))
for i in range(20):
background.paste(section, (0, (41 * i + 1)))
background.paste(separator, (0, (41 * i) + 41))
else:
background.paste(separator, (0, 0))
for i in range(20):
# background.paste(section,(0,(41*i+1)))
background.paste(separator, (0, (41 * i) + 41))
draw = ImageDraw.Draw(background)
fnt = ImageFont.truetype("Fonts/PIXEAB__.ttf",36)
draw.text((10, 10), names[0], font=fnt, fill=(0, 0, 0))
background.show()
ImageDraw has an undocumented member fontmode, which can be set to '1' (cf. Pillow's image modes) to turn off the anti-aliasing of the rendered text.
Let's compare common rendered text, draw.fontmode is implicitly set to 'L':
from PIL import Image, ImageDraw, ImageFont
image = Image.new('RGB', (800, 200), (255, 255, 255))
draw = ImageDraw.Draw(image)
font = ImageFont.truetype('arial.ttf', 150)
draw.text((10, 10), 'Hello World', font=font, fill=(0, 0, 0))
image.save('image.png')
Now, let's explicitly set draw.fontmode = '1':
from PIL import Image, ImageDraw, ImageFont
image = Image.new('RGB', (800, 200), (255, 255, 255))
draw = ImageDraw.Draw(image)
draw.fontmode = '1'
font = ImageFont.truetype('arial.ttf', 150)
draw.text((10, 10), 'Hello World', font=font, fill=(0, 0, 0))
image.save('image.png')
Et voilà – no anti-aliasing, all pixels are solid black.
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
PyCharm: 2021.1
Pillow: 8.2.0
----------------------------------------
I use python OpenCV (Windows 10, Python 2.7) to write text in image, when the text is English it works, but when I use Chinese text it write messy code in the image.
Below is my code:
# coding=utf-8
import cv2
import numpy as np
text = "Hello world" # just work
# text = "内容理解团队" # messy text in the image
cv2.putText(img, text,
cord,
font,
fontScale,
fontColor,
lineType)
# Display the image
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
When text = "Hello world" # just work, below is the output image:
When text = "内容理解团队" # Chinese text, draw messy text in the image, below is the output image:
What's wrong? Does opencv putText don't support other language text?
The cv2.putText don't support no-ascii char in my knowledge. Try to use PIL to draw NO-ASCII(such Chinese) on the image.
import numpy as np
from PIL import ImageFont, ImageDraw, Image
import cv2
import time
## Make canvas and set the color
img = np.zeros((200,400,3),np.uint8)
b,g,r,a = 0,255,0,0
## Use cv2.FONT_HERSHEY_XXX to write English.
text = time.strftime("%Y/%m/%d %H:%M:%S %Z", time.localtime())
cv2.putText(img, text, (50,50), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (b,g,r), 1, cv2.LINE_AA)
## Use simsum.ttc to write Chinese.
fontpath = "./simsun.ttc" # <== 这里是宋体路径
font = ImageFont.truetype(fontpath, 32)
img_pil = Image.fromarray(img)
draw = ImageDraw.Draw(img_pil)
draw.text((50, 80), "端午节就要到了。。。", font = font, fill = (b, g, r, a))
img = np.array(img_pil)
cv2.putText(img, "--- by Silencer", (200,150), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (b,g,r), 1, cv2.LINE_AA)
## Display
cv2.imshow("res", img);cv2.waitKey();cv2.destroyAllWindows()
#cv2.imwrite("res.png", img)
Refer to my another answer:
Load TrueType Font to OpenCV
According to this opencv forum, putText is only able to support a small ascii subset of characters and does not support unicode characters which are other symboles like chinese and arabic characters.
However, you can try to use PIL instead and follow the answer posted here and see if it works out for you.
Quick Start
np_img = np.ones((64, 32, 3), dtype=np.uint8) * 255 # background with white color
draw_text = init_parameters(cv2_img_add_text, text_size=32, text_rgb_color=(0, 0, 255), font='kaiu.ttf', replace=True)
draw_text(np_img, '您', (0, 0))
draw_text(np_img, '好', (0, 32))
cv2.imshow('demo', np_img), cv2.waitKey(0)
what is init_parameters() and cv2_img_add_text()?
see as below:
EXAMPLE
from typing import Tuple
import numpy as np
import cv2
from PIL import Image, ImageDraw, ImageFont
# define decorator
def init_parameters(fun, **init_dict):
"""
help you to set the parameters in one's habits
"""
def job(*args, **option):
option.update(init_dict)
return fun(*args, **option)
return job
def cv2_img_add_text(img, text, left_corner: Tuple[int, int],
text_rgb_color=(255, 0, 0), text_size=24, font='mingliu.ttc', **option):
"""
USAGE:
cv2_img_add_text(img, '中文', (0, 0), text_rgb_color=(0, 255, 0), text_size=12, font='mingliu.ttc')
"""
pil_img = img
if isinstance(pil_img, np.ndarray):
pil_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(pil_img)
font_text = ImageFont.truetype(font=font, size=text_size, encoding=option.get('encoding', 'utf-8'))
draw.text(left_corner, text, text_rgb_color, font=font_text)
cv2_img = cv2.cvtColor(np.asarray(pil_img), cv2.COLOR_RGB2BGR)
if option.get('replace'):
img[:] = cv2_img[:]
return None
return cv2_img
def main():
np_img = np.ones(IMG_SHAPE, dtype=np.uint8) * 255 # background with white color
np_img = cv2_img_add_text(np_img, 'Hello\nWorld', (0, 0), text_rgb_color=(255, 0, 0), text_size=TEXT_SIZE)
np_img = cv2_img_add_text(np_img, '中文', (0, LINE_HEIGHT * 2), text_rgb_color=(0, 255, 0), text_size=TEXT_SIZE)
cur_y = LINE_HEIGHT * 3
draw_text = init_parameters(cv2_img_add_text, text_size=TEXT_SIZE, text_rgb_color=(0, 128, 255), font='kaiu.ttf', replace=True)
for msg in ('笑傲江湖', '滄海一聲笑'):
draw_text(np_img, msg, (0, cur_y))
cur_y += LINE_HEIGHT + 1
draw_text(np_img,
"""123
456
789
""", (0, cur_y))
cv2.imshow('demo', np_img), cv2.waitKey(0)
if __name__ == '__main__':
IMG_HEIGHT, IMG_WIDTH, CHANNEL = IMG_SHAPE = (250, 160, 3)
TEXT_SIZE = LINE_HEIGHT = 32
main()
EDIT: added complete working example
I have the following program:
from PIL import Image, ImageDraw, ImageFont
FULL_SIZE = 50
filename = 'font_test.png'
font="/usr/share/fonts/truetype/msttcorefonts/arial.ttf"
text="5"
image = Image.new("RGBA", (FULL_SIZE, FULL_SIZE), color="grey")
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(font, 40)
font_width, font_height = font.getsize(text)
draw.rectangle(((0, 0), (font_width, font_height)), fill="black")
draw.text((0, 0), text, font=font, fill="red")
image.save(filename, "PNG")
This generates the following image:
It seems that when writing the text PIL library adds some margin at the top. This margin depends on the font I use.
How can I take this into account when trying to position the text (I want it to be in the middle of a rectangle)?
(Using Python 2.7.6 with Pillow 2.3.0 on Ubuntu 14.04)
I don't understand why, but subtracting font.getoffset(text)[1] from the y co-ordinate fixes it on my computer.
from PIL import Image, ImageDraw, ImageFont
FULL_SIZE = 100
filename = 'font_posn_test.png'
fontname = '/usr/share/fonts/truetype/msttcorefonts/arial.ttf'
textsize = 40
text = "5"
image = Image.new("RGBA", (FULL_SIZE, FULL_SIZE))
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(fontname, textsize)
print font.getoffset(text)
print font.font.getsize(text)
font_width, font_height = font.getsize(text)
font_y_offset = font.getoffset(text)[1] # <<<< MAGIC!
draw.rectangle(((0, 0), (font_width, font_height)), fill="black")
draw.text((0, 0 - font_y_offset), text, font=font, fill="red")
image.save(filename, "PNG")