I have a list, for example, a txt file, each line is a person’s name, and I need to convert each person’s name to one image.
Problem Refinement
Data input, here is relatively simple, is to read the names.txt file. Each line in the file is a person’s name, with no extra information, like this:
1
2
3
4
5
6
7
8
9
10
11
12
Linda Wilson
Karl Walker
Ezekiel Brown
Chelsea Resnick
Bryan Dijkhuizen
Jessey Anthony
Suzanne Berger
Joseph Mavericks
Matthew Coast
Bill Petro
Lipika Sahu
Mona Lazar
Picture format requirements. Here is an A4 paper size picture for subsequent printing (the standard size of A4 paper is: 210*297 mm). The name of the person must be enlarged to fill the A4 paper.
Save the image to the output subdirectory of the directory where the names.txt file is located.
Program Implementation
The problem is relatively simple and there are many solutions. I use Python program to solve it here.
Read File Data
The first step is to read the file content. This step is relatively simple yet:
1
2
withopen(filename,"r")asf:data=f.readlines()
Directly read the content of each line and save it to an array.
Pay attention to the data read in this way. The last one has a newline character, which needs to be removed.
Generate image content
Then you can use Python’s Pillow library to implement the text drawing function. First install the Pillow library, you can use pip install pillow to install it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Create an A4 size white pictureimage=Image.new('RGB',(2100,2970),'white')draw=ImageDraw.Draw(image)# Load your favorite fontsfont=ImageFont.truetype('/System/Library/Fonts/Supplemental/Arial.ttf',36)# Calculate text width and heighttext_width,text_height=draw.textsize(name,font=font)# Calculate where to place textx=(2100-text_width)/2y=(2970-text_height)/2# Write people's names into picturedraw.text((x,y),name,font=font,fill='black')
But there is a problem. The font size here is set manually to 36, and the characters in the picture are very small.
Of course, you can keep trying and adjust it to a suitable size, but names can be long or short.
If you want the effect of filling the picture with the person’s name just right, you need to dynamically adjust the font size here.
You can increase the font size until the text fills the entire image. The core processing logic is as follows:
1
2
3
4
5
6
7
8
9
# Keep increasing the font size until the text fills the entire imagefont_size=16whileTrue:# Load your favorite fontsfont=ImageFont.truetype(font_name,font_size)text_width,text_height=font.getsize(name)iftext_width>image_widthortext_height>image_height:breakfont_size+=1
The effect obtained this time is OK. Each person’s name can completely cover the entire width of the image, as shown in the figure:
importosfromPILimportImage,ImageDraw,ImageFontdefgenerate_name_image(name,number,output_path):# Modify it to the font file on your own computer (your favorite)font_name='/System/Library/Fonts/Supplemental/Arial.ttf'image_width=2100image_height=2970font_size=16# Keep increasing the font size until the text fills the entire imagewhileTrue:# Load your favorite fontsfont=ImageFont.truetype(font_name,font_size)text_width,text_height=font.getsize(name)iftext_width>(image_width-20)ortext_height>(image_height-20):breakfont_size+=1# Recalculate placementx=(image_width-text_width)/2y=(image_height-text_height)/2# Create a picture and write the person's nameimage=Image.new('RGB',(image_width,image_height),'white')draw=ImageDraw.Draw(image)draw.text((x,y),name,font=font,fill='black')# Save pictureimage.save(f'{output_path}/{number}.jpg')defload_data(filename):output_path="output"ifnotos.path.exists(output_path):# whether the folder existsos.makedirs(output_path)# not exist, create itwithopen(filename,"r")asf:data=f.readlines()foriinrange(len(data)):text=data[i].strip('\r\n ')# Remove newline charactersprint(text)generate_name_image(text,i+1,output_path)load_data('names.txt')