rundes Bild darstellen

Fragen zu Tkinter.
Antworten
Louis19
User
Beiträge: 18
Registriert: Mittwoch 17. Juni 2009, 12:07

Hallo,

ich hab folgendes Problem:

Für eine kleines Roulettspiel hätte ich ganz gerne so einen Roulettkessel auf meiner Benutzeroberfläche angezeigt. Das Problem ist bloß, dass dabei der weiße Rand vom Bild nicht außgeblendet wird, sondern voll sichtbar ist auf meinem grünen Hintergrund zu sehen ist. :(
Weiß wer wie ich diesen ausblende ?

Um Hilfe würde ich mich sehr freuen.

Gruß
Louis19

mein bisheriger Programmcode:

Code: Alles auswählen

# roulett.pyw
# ------------------------------------

from Tkinter import *

class Roulett(object):
    
    def __init__(self):
        self.fenster = Tk()
        self.fenster.title('Roulett')
        self.c = Canvas(self.fenster, width='10c', height='10c', bg='green')
        self.c.pack()
        self.bild = PhotoImage(file="Bild_Roulettkessel.gif")
        self.bildfaeche = self.c.create_image('5c','5c',image=self.bild)
        self.fenster.mainloop()

r = Roulett()
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Louis19 hat geschrieben:Weiß wer wie ich diesen ausblende ?
Indem du das Bild mit einem Bildbearbeitungsprogramm deiner Wahl bearbeitest und die unerwünschte weiße Farbe in Transparenz umwandelst.
Louis19
User
Beiträge: 18
Registriert: Mittwoch 17. Juni 2009, 12:07

ja das hatte ich mir auch schon überlegt, aber spätestens beim abspeichern ist die Fläche wieder weiß.
Louis19
User
Beiträge: 18
Registriert: Mittwoch 17. Juni 2009, 12:07

Bei dem Bild handelt es sich übrigens um das hier, bei dem Rand (und auch das Innere) zunächst transparent ist :
http://www.gefilde.de/ashome/vorlesunge ... kessel.gif
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Zwar habe ich es jetzt nicht mit xturtle, sondern mit frog ausprobiert, aber da beide Module ein Tkinter-Canvas verwenden, sollte das egal sein. Das von dir gezeigte Bild hat dort einen (im wesentlichen, bis auf einige verstreute Pixel) transparenten Hintergrund.
Louis19
User
Beiträge: 18
Registriert: Mittwoch 17. Juni 2009, 12:07

also müsste es eigentlich ohne Rand klappen !?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Louis19 hat geschrieben:also müsste es eigentlich ohne Rand klappen !?
Ja.
Louis19
User
Beiträge: 18
Registriert: Mittwoch 17. Juni 2009, 12:07

ok, ich hab das jetzt irgendwie hinbekommen :D

Wenn ich das sich jetzt drehen lassen möchte, gibt es dafür in Tkinter eine Funktion, oder was müsste man da machen ?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Louis19 hat geschrieben:Wenn ich das sich jetzt drehen lassen möchte, gibt es dafür in Tkinter eine Funktion, oder was müsste man da machen ?
Du nimmst dir erneut ein Bildbearbeitungsprogramm deiner Wahl und drehst dein Ausgangsbild, sagen wir, jeweils immer um 10° weiter und speicherst es unter neuem Namen ab. Am Ende hast du dann 36 Einzelbilder.

In deinem Roulette-Programm spielst du die 36 Einzelbilder dann hintereinander ab ...
Louis19
User
Beiträge: 18
Registriert: Mittwoch 17. Juni 2009, 12:07

Also Tkinter kann das Bild selber nicht drehen ?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Louis19 hat geschrieben:Also Tkinter kann das Bild selber nicht drehen ?
Nein. Du könntest aber die PIL verwenden und mittels der rotate()-Methode dein Bild jeweils um den gewünschten Winkel drehen lassen und das dann als Tkinter-PhotoImage verwenden. Dazu benötigst du das Modul ImageTk aus der PIL.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Louis19

Hier etwas zum ausprobieren mit PIL:

Code: Alles auswählen

import Tkinter as tk
import Image, ImageTk, ImageFont, ImageDraw

def draw_image(pil_image, angle=0):
    pil_image = pil_image.rotate(angle)
    app_win.roulette_image = ImageTk.PhotoImage(pil_image)
    canvas.itemconfigure('roulette', image=app_win.roulette_image)

def animate():

    draw_image(pil_roulette_image, app_win.angle_counter)

    if app_win.angle_counter < 359:
        app_win.angle_counter += 1
    else:
        app_win.angle_counter = 0

    app_win.after(100, animate)

app_win = tk.Tk()

app_win.tk_roulette_image = None
app_win.angle_counter = 0

pil_roulette_image = Image.open("roulette_kessel.png")

canvas = tk.Canvas(app_win, bg='white', width=400, height=400, bd=1,
    highlightthickness=0)
canvas.pack()

canvas.create_image(20, 20, image=None, anchor='nw',
    tag='roulette')

animate()

app_win.mainloop()
Wichtig das Roulettebild muss in das 'png'-Format umgewandelt werden! (z.B. mit Gimp)

Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

wuf hat geschrieben:Wichtig das Roulettebild muss in das 'png'-Format umgewandelt werden!
Ja und nein. Die reine Umwandlung vom indizierten gif ins png-Format bringt nichts, wenn dabei nicht vom indizierten ins RGB-Format umgewandelt wird. Verwendet man für die Umwandlung von gif -> png z.B. optipng, dann hat man eine indizierte png-Datei und es passiert das gleiche wie mit der gif-Datei beim Rotieren: Die Transparenz geht kaputt.

Was ich schon befürchtet hatte: Die Berechnungen für die Rotation sind zu teuer, als dass man eine auch nur halbwegs saubere Animation der Drehung hinbekommt (oder aber mein Rechner ist noch leistungsschwächer als ich ohnehin schon dachte).

Ergänzung: Wenn man beim Start des Programms einmalig 12 Bilder jeweils um 30° weitergedreht vorproduziert und diese dann z.B. alle 20-30 ms abruft, bekommt man eine einwandfreie, flüssige Animation.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

........ Hier noch eine verbesserte Variante in Sicht auf die Transparenz. Die Performance lässt aber noch zu wünschen übrig:

http://paste.pocoo.org/show/177443/

Das Orginalbild enthielt noch Verunreinigungen was die Hintergrundfarbe anbelangte. Entfernte diese noch mit GIMP. Das Bild wird in ein Photoimage-Object im 'RGBA'-Modus kopiert bevor es mit Tk in der Canvas angezeigt wird.

Gruss wuf :wink:
Take it easy Mates!
Louis19
User
Beiträge: 18
Registriert: Mittwoch 17. Juni 2009, 12:07

Ok vielen Dank!
:D
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

...... Hier noch eine leicht optimierte Variante:

http://paste.pocoo.org/show/177513/
http://paste.pocoo.org/show/177515/ (korrigiert)

Da für das Roulette eigentlich nur das Drehkreuz drehen muss, könnte die Sache noch mehr optimiert werden.

Gruss wuf :wink:
Take it easy Mates!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

numerix hat geschrieben:Was ich schon befürchtet hatte: Die Berechnungen für die Rotation sind zu teuer, als dass man eine auch nur halbwegs saubere Animation der Drehung hinbekommt (oder aber mein Rechner ist noch leistungsschwächer als ich ohnehin schon dachte).
Also die Rotation von Sprites hat damals, auf meinem Rechner von 2001 in Pygame durchaus flüssig funktioniert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Leonidas

Ja irgend etwas muss da bei der PIL-Programmierung in die Hosen gegangen sein. Könnte evtl. mit einer Zeitraffersprache erstellt worden sein.

Gruss wuf :wink:
Take it easy Mates!
Antworten