Seite 1 von 1

rundes Bild darstellen

Verfasst: Freitag 12. Februar 2010, 20:49
von Louis19
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()

Re: rundes Bild darstellen

Verfasst: Freitag 12. Februar 2010, 20:59
von numerix
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.

Verfasst: Freitag 12. Februar 2010, 21:02
von Louis19
ja das hatte ich mir auch schon überlegt, aber spätestens beim abspeichern ist die Fläche wieder weiß.

Verfasst: Freitag 12. Februar 2010, 21:14
von Louis19
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

Verfasst: Freitag 12. Februar 2010, 23:10
von numerix
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.

Verfasst: Samstag 13. Februar 2010, 00:05
von Louis19
also müsste es eigentlich ohne Rand klappen !?

Verfasst: Samstag 13. Februar 2010, 08:01
von numerix
Louis19 hat geschrieben:also müsste es eigentlich ohne Rand klappen !?
Ja.

Verfasst: Samstag 13. Februar 2010, 09:43
von Louis19
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 ?

Verfasst: Samstag 13. Februar 2010, 09:59
von numerix
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 ...

Verfasst: Samstag 13. Februar 2010, 11:13
von Louis19
Also Tkinter kann das Bild selber nicht drehen ?

Verfasst: Samstag 13. Februar 2010, 11:30
von numerix
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.

Verfasst: Samstag 13. Februar 2010, 12:15
von wuf
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:

Verfasst: Samstag 13. Februar 2010, 12:44
von numerix
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.

Verfasst: Samstag 13. Februar 2010, 13:24
von wuf
........ 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:

Verfasst: Samstag 13. Februar 2010, 14:29
von Louis19
Ok vielen Dank!
:D

Verfasst: Samstag 13. Februar 2010, 17:41
von wuf
...... 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:

Verfasst: Samstag 13. Februar 2010, 22:00
von Leonidas
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.

Verfasst: Samstag 13. Februar 2010, 22:17
von wuf
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: