Can't print image - python

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.

Related

PIL Writing Text on Image Using Escape Sequence

`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()

How do I reduce the number of colors used in ImageDraw.text

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
----------------------------------------

How do I center my text on an image using PIL in python and save the image with a different name in a for or while loop?

I'm trying to extract information from a word doc and write the paragraphs from there into images with borders and in the center of the image. In addition to this, I'm trying to save the image after each iteration, but with a different name, preferably like "patentDayMonthYearTime.png" that way it simply goes in chronological order.
import time
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
from docx import Document
doc = Document('test.docx')
fullText = []
for para in doc.paragraphs:
W, H = 300, 300
body = Image.new('RGB', (W, H), (255, 255, 255))
border = Image.new('RGB', (W+2, H+2), (0, 0, 0))
border.save('border.png')
body.save('body.png')
patent = Image.open('border.png')
patent.paste(body, (1, 1))
draw = ImageDraw.Draw(patent)
font = ImageFont.load_default()
text = para.text.encode('utf-8')
ch, pad = 60, 20
for line in text:
w, h = draw.textsize(line, font=font)
draw.text(((W-w)/2, ch), line, (0, 0, 0), font=font)
ch += h + pad
date = time.strftime("%Y-%m-%d-%H:%M")
patent.save('patent.png')
Above is my current code, and with it, I'm receiving the following error:
Traceback (most recent call last):
File "C:/Users/crazy/PycharmProjects/Patent/patent.py", line 28, in
w, h = draw.textsize(line, font=font)
File "C:\Users\crazy\PycharmProjects\Patent\venv\lib\site-packages\PIL\ImageDraw.py", line 423, in textsize
if self._multiline_check(text):
File "C:\Users\crazy\PycharmProjects\Patent\venv\lib\site-packages\PIL\ImageDraw.py", line 258, in _multiline_check
return split_character in text
TypeError: argument of type 'int' is not iterable
Here is the document I'm currently working with:
You're iterating over each letter, not each paragraph. I've fixed it and also added date into output filename. Here is the code:
import time
import textwrap
from docx import Document
from PIL import Image, ImageFont, ImageDraw
W, H = 300, 300
doc = Document('file.docx')
fullText = []
for i, p in enumerate(doc.paragraphs):
body = Image.new('RGB', (W, H), (255, 255, 255))
patent = Image.new('RGB', (W + 2, H + 2), (0, 0, 0))
patent.paste(body, (1, 1))
draw = ImageDraw.Draw(patent)
font = ImageFont.load_default()
current_h, pad = 60, 20
for line in textwrap.wrap(p.text, width=40):
w, h = draw.textsize(line, font=font)
draw.text(((W - w) / 2, current_h), line, (0, 0, 0), font=font)
current_h += h + pad
patent.save(f'patent_{i+1}_{time.strftime("%Y%m%d%H%M%S")}.png')
Output files:
patent_1_20201211092732.png:
patent_2_20201211092732.png:
patent_3_20201211092732.png:

How to draw Chinese text on the image using `cv2.putText`correctly? (Python+OpenCV)

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()

Python image library - font positioning

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")

Categories