0

空白のテキストボックス(通常は手書き)で書かれた(.png形式の)書式があります。ボックスにテキストを入力したいと思います。tkinterキャンバスとPIL画像(Python)でのピクセル座標の調整

これを行うには、画面上にフォームを表示するためにtkinterを使用しています。次に、マウスの矢印キーを使用して細かい位置を指定して、ボックスのピクセル座標を取得し、次にPILを使用してボックス。実際の例を以下に示します。

私の主な問題は、tkinterキャンバスのピクセル座標とPILイメージのピクセル座標を整列させることです。

追加の背景。画像は高解像度で、4961年頃には7016ピクセルです。私の画面解像度は1920 x 1080です。私はこのように書くのに必要なテキストを書くのに問題があり、画面内に完全に収まるように画像を拡大すると大きな成功を収めました。画面のピクセルを画像のピクセルと混同していたためです(この2つを整列させるためにイメージを画面に合わせると解決されましたが、ここでの違いを理解し、スケーリングせずにこのタスクを実行する方法は、また役に立つ)。

しかし、私はtkinterキャンバスのピクセル座標をPIL画像と調整するのにも問題があります。たとえば、以下のコードは、(x、y)ピクセル座標を書き込んだ後、そのページの相対座標(ページの横のx%、ページの上のy%)をボックスに書き込むように設計されています別のプロセス)。例:(346,481)>> {49.856,51.018}

しかし、(0.14のスケーリング係数を使用して)イメージの下部までクリックすると、(209,986)>> {30.115、-0.407}。相対性は0から100%の間にあるべきですので、負であってはいけません。PILが生成した.pngファイルではこれを見ることができません。

スケーリング係数0.125を使用すると、tkinterキャンバスボックスにテキストを書き込むことはできますが、ドライブに保存されているPIL .pngファイルのテキストはかなり外側に表示されます。だから、これらの2つのシステム間で何かが明らかに機能していない。

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に非常に近いはずです。オフの場合は、キャンバスの左上隅からウィンドウの左上隅までの距離だけずれている可能性があります。

関連する問題