У меня есть форма (в формате .png) с пустыми текстовыми полями (обычно заполняются вручную). Я хотел бы заполнить поля текстом.
Для этого я использую tkinter для отображения формы на экране, затем использую мышь (с более точным позиционированием с помощью клавиш со стрелками), чтобы получить пиксельные координаты поля, а затем использую PIL для записи текста в это поле. Рабочий пример ниже.
Моя основная проблема заключается в том, что я изо всех сил пытаюсь выровнять координаты пикселей на холсте tkinter и координаты пикселей в изображении PIL.
Какой-то дополнительный фон. Изображение имеет высокое разрешение и составляет около 4961 на 7016 пикселей. Разрешение моего экрана 1920 x 1080. У меня были проблемы с написанием текста там, где мне нужно было писать так, и я добился большего успеха, если масштабировал изображение, чтобы оно полностью помещалось на моем экране. Я могу только предположить, что это связано с тем, что я / путаю пиксели экрана с пикселями изображения (и решил это, когда я подогнал изображение к экрану, чтобы выровнять эти два, но понимание различий здесь и как выполнить эту задачу без масштабирования было бы наиболее тоже полезно).
Но у меня также возникают проблемы с согласованием координат пикселей на холсте tkinter с изображением PIL. Например, приведенный ниже код предназначен для записи (x, y) координат пикселей, а затем его относительности страницы {x% по странице, y% вверх по странице} в поле (причина этого в том, что это входные данные в другой процесс). Пример: (346, 481) >> {49,856, 51,018}
Но если (используя коэффициент масштабирования 0,14) я щелкну очень низко в нижней части изображения, я получу (209, 986) >> {30,115, -0,407}. Относительность должна быть ограничена от 0 до 100%, поэтому не должна быть отрицательной, и я не вижу этого в моем файле .png, созданном PIL.
Если я использую коэффициент масштабирования 0,125, я могу нормально писать текст в поле холста tkinter, но текст выглядит немного ниже (то есть вне поля) в файле PIL .png, который сохраняется на дисках. Так что между этими двумя системами явно что-то не работает.
Как я могу согласовать координаты пикселей PIL и tkinter?
Кроме того, у меня есть четыре отдельные функции для более точной настройки клавиш. В идеале это была бы одна функция, но я не мог заставить кнопки со стрелками (и т. д.) работать внутри блока if elif (например, я пробовал это и некоторые другие производные от левого, правого и т. д.)
def mouseMovement(event):
moveSpeed = 1
try:
int(event.char)
moveSpeed = max(1, int(event.char)*5)
return True
except ValueError:
return False
x, y = pyautogui.position()
if event.char == '<Left>':
pyautogui.moveTo(x-moveSpeed, y)
elif event.char == '<Right>':
pyautogui.moveTo(x+moveSpeed, y)
root.bind('<Key>' , mouseMovement)
Любая помощь очень ценится!
Почти рабочий пример ниже:
from tkinter import *
from PIL import Image, ImageDraw, ImageFont, ImageTk
import pyautogui
# Form
formName = '2013+ MCS4'
# PIL image'
formImage = Image.open(formName+'.png')
wForm, hForm = formImage.size
scale = 0.14
formImage = formImage.resize((int(scale*wForm), int(scale*hForm)), Image.ANTIALIAS)
draw = ImageDraw.Draw(formImage)
font = ImageFont.truetype('arial.ttf', 10)
textColor = (255, 40, 40)
# tkinter canvas
def colorConversion(RGB):
def hexadecimalScale(RGB):
hexadecimalSystem = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F')
return str(hexadecimalSystem[RGB//16]) + str(hexadecimalSystem[RGB%16])
return '#' + hexadecimalScale(RGB[0]) + hexadecimalScale(RGB[1]) + hexadecimalScale(RGB[2])
fontCanvas = 'arial 7'
textColorCanvas = colorConversion(textColor)
# generate canvas
if __name__ == '__main__':
root = Tk()
# set up tkinter canvas with scrollbars
frame = Frame(root, bd=2, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
xscroll = Scrollbar(frame, orient=HORIZONTAL)
xscroll.grid(row=1, column=0, sticky=E+W)
yscroll = Scrollbar(frame)
yscroll.grid(row=0, column=1, sticky=N+S)
canvas = Canvas(frame, width=int(scale*wForm), height=int(scale*hForm), bd=0, xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
xscroll.config(command=canvas.xview)
yscroll.config(command=canvas.yview)
frame.pack(fill=BOTH,expand=1)
# add image
#img = PhotoImage(file=formName+'.png')
img = ImageTk.PhotoImage(formImage)
canvas.create_image(0,0,image=img,anchor="nw")
canvas.config(scrollregion=canvas.bbox(ALL))
wForm = img.width()
hForm = img.height()
# finer mouse movements
moveSpeed = 1
def setMoveSpeed(event):
global moveSpeed
try:
int(event.char)
moveSpeed = max(1, int(event.char)*5)
return moveSpeed
except ValueError:
return False
def moveMouseLeft(event):
x, y = pyautogui.position()
pyautogui.moveTo(x-moveSpeed, y)
def moveMouseRight(event):
x, y = pyautogui.position()
pyautogui.moveTo(x+moveSpeed, y)
def moveMouseUp(event):
x, y = pyautogui.position()
pyautogui.moveTo(x, y-moveSpeed)
def moveMouseDown(event):
x, y = pyautogui.position()
pyautogui.moveTo(x, y+moveSpeed)
root.bind('<Key>' , setMoveSpeed)
root.bind('<Left>' , moveMouseLeft)
root.bind('<Right>', moveMouseRight)
root.bind('<Up>' , moveMouseUp)
root.bind('<Down>' , moveMouseDown)
# print coordinates
def printCoordinates(event):
x = event.x # minor adjustments to correct for differences in tkinter vs PIL methods (investigate further)
y = event.y # minor adjustments to correct for differences in tkinter vs PIL methods (investigate further)
canvas.create_text(x, y-5, fill= textColorCanvas, font= fontCanvas, anchor= 'sw',
text= '{'+str(round(x/wForm*100,3))+', '+str(round((1-y/hForm)*100,3))+'}' )
draw.text( (x, y-5), '{'+str(round(x/wForm*100,3))+', '+str(round((1-y/hForm)*100,3))+'}' , fill=textColor, font=font)
print('('+str(x)+', '+str(y)+') >> {'+str(round(x/wForm*100,3))+', '+str(round((1-y/hForm)*100,3))+'}')
root.bind('<Return>', printCoordinates)
root.mainloop()
formImage.save('coordinates - '+formName+'.png')