Tkinter App, Turtle ein JPG Skin zuweisen

Fragen zu Tkinter.
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

Also die while-schleife muss wohl in die mainloop() Bei meinem Proframm gibt mir 'img.getpixel((x, y))' nur 0, 0, 0, 0. Wie kann ich das beheben?

Code: Alles auswählen

import turtle
import tkinter as tk
from PIL import Image, ImageTk
NORTH = 90
SOUTH = 270
EAST = 0
WEST = 180
MOVE_STEP = 10
ANGLE_STEP = 90


def forward():
    turtle.setheading(NORTH)

def backward():
    turtle.setheading(SOUTH)

def left():
    angle = turtle.heading()
    angle += ANGLE_STEP
    turtle.setheading(angle)

def right():
    angle = turtle.heading()
    angle -= ANGLE_STEP
    turtle.setheading(angle)

# Initial setup
screen = turtle.Screen()

bg_image = tk.PhotoImage(file="Labyrinth.png")
bg_image_width = bg_image.width()
bg_image_height = bg_image.height()
#print("Grösse des Hintergrundbildes: {}x{}".format(
    #bg_image_width, bg_image_height))
screen.setup(bg_image_width, bg_image_height)
canvas = screen.getcanvas()
canvas.create_image(0, 0, image=bg_image)

turtle.penup()
turtle.speed(0)
turtle.goto(0, 0)
turtle.setheading(EAST)
turtle.showturtle()

# Keyboard actions
screen.listen()
screen.onkey(forward, "w")
screen.onkey(backward, "s")
screen.onkey(left, "a")
screen.onkey(right, "d")

fd = 1
x = turtle.xcor()
y = turtle.ycor()
ende = False
while not ende:
    turtle.forward(fd)
    img = Image.open("Labyrinth.png")
    a = img.getpixel((x, y))
    print(a)

screen.listen()
turtle.mainloop()
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

Bei JPG hatte ich das Problem nicht. So wie ich das jetzt im Internewt lese hat PNG auch noch einen "Alphakanal". Liegt das vllt daran?
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

Ich habe mir jetzt mal eine komplett schwarzes Bild erstellt (Black.png) und für Labyrinth.png eingesetzt. Hier erhalte ich jetzt nur noch 3 Ziffern aber jede Ziffer hat den wert 0. Danach habe ich mir ein halb shwarz, halb weiß gefärbtes bild erstellt und hier bekam ich wieder nur 3 zahlen aber dafür hatten jetzt alle ziffern den wert 255. Ich bin jetzt wirklich verwirrt. 255 255 255 steht doch für weiß und 0 0 0 für Schwarz. Wieso verändern sich denn beim bewegen der turtle die Zahlen nicht?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Freddyyy: Lass Dir mal die Werte von `x` und `y` ausgeben.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

Habe jetzt die Variablen x und y in die shcliefe gepackt. Jetzt bekomme ich vernünftige werte. Aber die werte stimmen nicht mit dem Bild überein. Also manchmal bekomme ich 0 0 0 0 obwohl ich auf einem weißen Feld bin und andersherum.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Freddyyy

Deine Feststellung mit den Farben stimmt. Weiss = (255, 255, 255) und Schwarz = (0, 0, 0). Die Position der Turtle solltest du mit:
xpos, ypos = turtle.position()
abfragen können. Die Position der Turtle muss aus den Funktionen forward und backward abfragen werden.

Jetzt kommt das ein wenig verwirrende! Dein Turtle-Fenster enthält ein Vier-Quadranten Koordinatensystem. Das heisst links oben ist der Koordinatenpunkt (-500, 500), rechts unten (500, -500), in der Mitte ist dann (0, 0). Das mit tk.PhotoImage erzeugte Bild besitzt ein Ein-Quadranten Koordinatensystem. Hier ist links oben der Koordinatenpunkt (0, 0) und rechts unten (1000, 1000). Hier kannst du das Hirn ein wenig warm laufen lassen. :idea: (Ohne Gewähr ich bin Mathematiker)

Das automatische vorwärts bewegen der Turtle würde ich nicht mit einer while Schleife sondern mit canvas.after realisieren.

Gruss wuf ;-)
Take it easy Mates!
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

Der umrechnungs faktor den ich verwende (xcor()+500 ,ycor+500) funktioniert nur bei xcor().Also wenn ich die Turle sich nach links oder Rechts bewegt dann ist der Wert auf weißen Feldern (255, 255, 255, 255) und auf Schwarzen (0, 0, 0, 255). Aber wenn sich die turtle nach oben oder nach unten bewegt, dann ist der wert manchmal (0, 0, 0, 255auf weißen Feldern. Jemand ne idee woran das liegen kann?

LG Freddy

(PS ich bin jetzt bis DO weg und kann daher nicht auf Python zugreifen nur hier auf das Forum. Es sei denn man kann python auf hy installieren)
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

N.B. das mit:
(Ohne Gewähr ich bin Mathematiker :lol: )
war natürlich nur ein Witz.

Gruss wuf ;-)
Take it easy Mates!
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

Den vorherigen Beitrag habe ich geschrieben bevor ich deinen gelesen habe
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

Verstanden :D
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

Wenn ich ycor() so lasse dann habe ic hdas gleiche problem nur andersherum. :D
Das könnte etwas komplizierter werden als ich gedacht habe.
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

Also ehrlich gesagt verstehe ich das nicht. Ich habe die Punkte: -500, -500 (links unten); -500, 500 (links oben); 500, -500 (rechts unten); 500, 500 (rechts oben)
Wenn ich zu xcor() und ycor() immer 500 addiere dann habe ich dien Punkte: 0, 0 (links unten); 0, 1000 (links oben); 1000, 0 (rechts unten); 1000, 1000 (rechts oben)
Also wo liegt da der Fehler?
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Freddyyy

Die Bildbearbeitung wird ohne:
from PIL import Image, ImageTkdurchgeführt. An Stelle verwende ich tk.PhotoImage und erstelle damit ein normales tk-Bild, welches unter bg_image abgelegt ist. Für die Anzeige in Turtle wird es auf die mit canvas = screen.getcanvas() auf die Turtle-Canvas mittels canvas.create_image(0, 0, image=bg_image) gelegt. Die Abfrage nach den Pixelfarben erfolgt dann nicht mehr auf dem Turtle-Canvas-Bild sondern auf dem Abbild dessen, welches unter bg_image gespeichert ist. Für dessen Abfrage kannst du nicht die PIL-Modul-Methode img.getpixel((x, y) sondern du musst die Methode bg_image.get(x, y) hierfür verwenden!

Die folgenden Methoden:

Code: Alles auswählen

def forward():
    turtle.setheading(NORTH)

def backward():
    turtle.setheading(SOUTH)
würde ich belassen auf:

Code: Alles auswählen

def forward():
    turtle.forward(MOVE_STEP)

def backward():
    turtle.backward(MOVE_STEP)
Die Schrittdistanz musst du dann mit der Konstante MOVE_STEP festlegen. Die Fortbewegung der Turtle musst du dann durch Aufruf der Methode forward bewerkstelligen! Du siehst es wird langsam aber sicher komplex und Zeitaufwendig.

Gruss wuf ;-)
Take it easy Mates!
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

Jetzt bekomme ich diese Fehlermeldung:

Code: Alles auswählen

init__.py", line 3575, in get
    return self.tk.call(self.name, 'get', x, y)
_tkinter.TclError: expected integer but got "3.0"
Und wieso nicht die PIL Methode ? Bis auf die Umrechnung funmktioniert die doch ziemlich gut oder?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das mit der Y-Koordinate hatte ich vor vielen Beiträgen ja schon mal geschrieben: Die Werte im Canvas werden nach oben hin grösser, während sie im Bild nach unten hin grösser werden.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

@ blackjack und deswegen soll ich get(x,y) verwenden?
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Freddyyy

Hier noch der Zaubertrick für die Umwandlung der Turtle-Position in die Bild-Position für die Abfrage der Pixelwerte des Bildes:

Code: Alles auswählen

def border_check():
    xpos, ypos = turtle.position()
    bg_img_xpos = int(xpos + bg_width_offset)
    bg_img_ypos = int(bg_image_height - bg_width_offset - ypos)
    print("Border Check:", bg_img_xpos, bg_img_ypos)
    pixel_color = bg_image.get(bg_img_xpos, bg_img_ypos)
    print("Farbe:", pixel_color) 
Gruss wuf ;-)
Take it easy Mates!
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Freddyyy

Hier noch als Ergänzung die Bestimmung der XY-Offsetwerte:

Code: Alles auswählen

bg_image = tk.PhotoImage(file="labyrinth.png")
bg_image_width = bg_image.width()
bg_width_offset = bg_image_width / 2
bg_image_height = bg_image.height()
bg_height_offset = bg_image_height / 2
Gruss wuf ;-)
Take it easy Mates!
Freddyyy
User
Beiträge: 69
Registriert: Donnerstag 26. April 2018, 17:50

Ok Danke :D Funktioniert jetzt. Habe nochmal das Bild angepasst da viel zu wenig wege vorhanden waren.
Ich kann aber goto() nicht verwenden. Also wenn ich bzw turtle.goto(-500, 500) eingebe bewegt sich die Turtle kein Stück.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Freddyyy

Bei mir wird die Turtle in der linken oberen Ecke platziert. Um die Ursache des Fehlverhalten bei dir herauszufinden müsste man schon dein Skript sehen.

Gruss wuf ;-)
Take it easy Mates!
Antworten