我是使用Python的新手,我遇到了一个无法解决的问题。我想要做的是从excel电子表格包含三列(图像的地址,文本1和文本2),代码应选择第一个图像,然后插入属于其行的文本1和2 。我能够完成单个图像的代码,但是当我尝试处理所有图像时遇到问题。
import pandas as pd
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
ruta_excel = pd.read_excel('C:/Users/san_2/Documents/Script/ARCPY/Direc.xls',
sheet_name=0)
ruta = ruta_excel.iat[0, 0]
image_files = Image.open(ruta)
font_type = ImageFont.truetype('C:/Windows.old/Windows/Fonts/Arial.ttf',18)
draw = ImageDraw.Draw(image_files)
draw.text(xy=(20, 550), text=ruta_excel.iat[0, 1], fill=(255, 255, 255),
font=font_type)
draw.text(xy=(20, 570), text=ruta_excel.iat[0, 2], fill=(255, 255, 255),
font=font_type)
image_files.save(ruta, 'JPEG', quality=90)
谢谢
答案 0 :(得分:2)
我不知道PIL
但是如果你的代码适用于第一张图片而你的问题是迭代,那么你可以这样做:
import pandas as pd
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
ruta_excel=pd.read_excel('C:/Users/san_2/Documents/Script/ARCPY/Direc.xls',sheet_name=0)
# iterate over rows with itertuples
for row in ruta_excel.itertuples(index=False):
print (row) # to help you see what is happening but not necessary after
# row is tuple, doing row[0] access to the first item (the first column)
ruta=row[0]
image_files = Image.open(ruta)
font_type = ImageFont.truetype('C:/Windows.old/Windows/Fonts/Arial.ttf',18)
draw = ImageDraw.Draw(image_files)
# here you use row[1] and row[2]
draw.text(xy=(20,550),text= row[1],fill=(255,255,255),font=font_type)
draw.text(xy=(20,570),text= row[2],fill=(255,255,255),font=font_type)
image_files.save(ruta, 'JPEG', quality=90)
答案 1 :(得分:1)
您需要做的是循环pd.read_excel
找到的项目。此函数返回DataFrame
,因此您可以使用其三个内置迭代器之一:itertuples,iteritems或iterrows。
鉴于此示例XLS:
| | A | B | C |
| - | -------------- |--------------| --------------|
| 1 | /a/file/path/1 | first text 1 | second text 1 |
| 2 | /a/file/path/2 | first text 2 | second text 2 |
| 3 | /a/file/path/3 | first text 3 | second text 3 |
| 4 | /a/file/path/4 | first text 4 | second text 4 |
| 5 | /a/file/path/5 | first text 5 | second text 5 |
当使用pandas读取文件并且XLS中没有标题行时,您应指定header=None
并在names
中提供列名称。如果您有一个标题行并且它是XLS的第一行,则只需传递header=0
并省略names
。通过确保您可以将每个列映射到列名称,您可以使用itertuples
,因为您的用例是最合适的方法 - 您可以通过循环中的列名访问行值:
import pandas as pd
exc = pd.read_excel('file_text_map.xlsx', header=None, names=('file_path', 'text1', 'text2',))
for row in exc.itertuples(index=False):
print('file_path:', row.file_path, ', text1:', row.text1, ', text2:', row.text2)
这将导致
file_path: /a/file/path/1 , text1: first text 1 , text2: second text 1
file_path: /a/file/path/2 , text1: first text 2 , text2: second text 2
file_path: /a/file/path/3 , text1: first text 3 , text2: second text 3
file_path: /a/file/path/4 , text1: first text 4 , text2: second text 4
file_path: /a/file/path/5 , text1: first text 5 , text2: second text 5