0

빈 텍스트 상자 (일반적으로 손으로 채워짐)가있는 양식 (.png 형식)이 있습니다. 상자에 텍스트를 채우고 싶습니다.tkinter 캔버스 및 PIL 이미지 (Python)에서 픽셀 좌표 조정

이렇게하려면 tkinter를 사용하여 화면에 양식을 표시 한 다음 마우스의 화살표 키를 사용하여 미세한 위치 지정을 사용하여 상자의 픽셀 좌표를 가져온 다음 PIL을 사용하여 텍스트를 작성합니다. 상자. 아래에 실제 예제가 있습니다.

내 기본 문제는 tkinter 캔버스의 픽셀 좌표와 PIL 이미지의 픽셀 좌표를 정렬하는 데 어려움이 있습니다.

일부 추가 배경. 이미지는 고해상도이며 4961 픽셀 경에 7016 픽셀입니다. 내 화면 해상도는 1920 x 1080입니다. 필자는이 글을 쓰는 데 필요한 텍스트를 쓰는 데 문제가 있었으며 이미지를 화면 전체에 맞게 크기를 조정하면 큰 성공을 거두었습니다. 스크린 픽셀을 그림 픽셀과 혼동하고 있기 때문에 가정 만 할 수 있습니다. (이 두 가지를 정렬하기 위해 화면에 이미지를 맞출 때 이것을 해결했습니다. 그러나 여기에 차이점을 이해하고 크기 조정없이이 작업을 수행하는 방법이 가장 많을 것입니다. 도움이된다).

그러나 tkinter 캔버스의 픽셀 좌표를 PIL 그림과 조정하는 데 문제가 있습니다. 예를 들어, 아래의 코드는 (x, y) 픽셀 좌표를 작성한 다음 페이지 상대 비율 (페이지에서 가로 x %, 페이지에서 y %)을 상자에 쓰도록 설계되었습니다 (이 이유는 다른 프로세스). 예를 들면 다음과 같습니다. (346, 481) >> {49.856, 51.018}

이미지 크기가 매우 낮은 곳을 클릭하면 (209, 986) >> {30.115, -0.407}. 상대성은 0에서 100 % 사이로 제한되어야하므로 음수가 아니어야하며 내 PIL 생성 .png 파일에서이를 볼 수 없습니다.

0.125의 배율 인수를 사용하면 tkinter 캔버스 상자에 텍스트를 쓸 수 있지만 드라이브에 저장된 PIL .png 파일의 텍스트가 상자 밖에 표시됩니다. . 그래서이 두 시스템 사이에는 어떤 것이 명확하게 작동하지 않습니다.

어떻게 PIL과 tkinter 픽셀 좌표를 조정할 수 있습니까?

별도로 추가 키 조정을 처리 할 수있는 4 가지 기능이 있습니다. 이상적이 하나 개의 함수가 될 것입니다,하지만 난 화살표 버튼 (등)이있는 경우 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') 

답변

0

난 당신의 코드를 실행할 수 없습니다, 그래서 이것은 단지 추측입니다.

캔버스에 일반적으로 포커스가없고 바인딩이 루트 창에 있으므로, event.xevent.y의 값은 캔버스가 아닌 전체 창에 상대적 일 수 있습니다.

이것은 쉽게 결정해야합니다. 바인딩에서 좌표를 인쇄 한 다음 가능한 한 0,0에 가까운 캔바스 왼쪽 위 모서리를 클릭합니다. 좌표가 캔버스를 기준으로하는 경우 인쇄 된 좌표도 0,0에 매우 가깝습니다. 꺼져 있으면 캔버스의 왼쪽 위 모서리에서 창의 왼쪽 위 모퉁이까지 떨어져있을 수 있습니다.