Kapitel 17
Grafik
506
Erläuterung:
#1: Erzeugt leeres Bild-Objekt mit 200 mal 200 Pixeln.
#2: Wir berechnen eine Liste mit insgesamt 200 Zahlen zwischen –2 und +2 im Abstand von
0.01.
#3: Hier wird eine Liste von Tupeln (x, y) erzeugt, die (näherungsweise) zur Mandelbrot-
menge gehören. Ob ein Punkt
(x ,y) zur Mandelbrotmenge gehört, wird durch die private
Methode
__test() ermittelt.
#4: Die Tupel werden nun als blaue Punkte auf das PhotoImage-Objekt gezeichnet.
#5: Die Methode __test() interpretiert die beiden Argumente x und y als Real- bzw. Ima-
ginärteil einer komplexen Zahl und liefert den Wert
True, falls die komplexe Zahl x +j*y
zur Mandelbrotmenge gehört, und False sonst.
#6: Es werden nur die ersten 20 Glieder der Folge berechnet und geprüft, ob der Absolutwert
des
i-ten Folgegliedes noch kleiner als RADIUS ist. Die Mandelbrotmenge wird also nicht
exakt, sondern nur näherungsweise berechnet.
17.2.2 Fotos analysieren und verändern
Der große Vorteil digitaler Fotos ist bekanntlich, dass man sie nachbearbeiten kann. Zu
dunkle Fotos werden aufgehellt, bei rotstichigen Fotos kann der rote Farbanteil zurückge-
nommen werden, der Kontrast kann verstärkt werden usw. Für derartige Operationen müs-
sen die einzelnen Pixel des Bildes gelesen und verändert werden.
self.__zeichnen()
self.fenster.mainloop()
def __zeichnen(self):
intervall = [x/ZOOM for x in range(-100, 100)] #2
mandelbrot = [(x, y) for x in intervall
for y in intervall
if self.__test(x, y)] #3
for x, y in mandelbrot:
self.bild.put("#0000ff", (int(ZOOM*x+100), int(ZOOM*y+100))) #4
def __test (self, x, y): #5
c = x + 1j * y
z = 0
for i in range(20): #6
if abs (z)< RADIUS:
z = z*z – c
else: return False # nicht Element der Mandelbrotmenge
return True # Element der Mandelbrotmenge
m = Mandelbrot()
507
17.2
Die Klasse PhotoImage
Das folgende Skript demonstriert die Verwendung der PhotoImage-Methoden get() und
put() zur Bearbeitung eines Fotos. Der Aufruf bild.get(x, y) liefert einen String mit drei
Dezimalzahlen zwischen
0 und 255, die durch Leerzeichen getrennt sind. Dieser String
stellt den RGB-Wert des Pixels an der Stelle
(x, y) dar. Beispiel: Wenn ein Bild an der Posi-
tion
(10, 20) ein rein blaues Pixel besitzt, liefert bild.get(10, 20) den String "0 0 255".
Die Applikation mit GUI ermöglicht es, ein Foto aus einer GIF-Datei zu laden und als Nega-
tiv darzustellen.
Abb. 17.7: Positiv und Negativ eines Fotos
Skript:
# photoviewer.pyw
from tkinter import filedialog, Label, Tk, Button, \
PhotoImage, LEFT
DEFAULT_PATH = "bilder/strasse.gif"
class FotoViewer:
def __init__ (self):
self.__createWidgets()
self.__layout()
self.fenster.mainloop()
def __createWidgets(self):
self.fenster = Tk()
self.bild = PhotoImage(file=DEFAULT_PATH)
self.bildflaeche = Label(master=self.fenster,
image=self.bild)
self.buttonLaden = Button(master=self.fenster,
Kapitel 17
Grafik
508
Erläuterung:
#1: Hier wird ein Fenster zur Auswahl einer Datei auf den Bildschirm gebracht. Die aufge-
rufene Methode gibt einen String zurück, der den vollständigen Pfad der ausgewählten
Datei enthält, sofern der Benutzer die Aktion nicht abgebrochen hat. Wenn abgebrochen
wurde, wird ein leerer String zurückgegeben.
#2: Wir erzeugen einen Generator für die Folge aller Punkte des Fotos. Ein Generator ist des-
halb geeignet, weil wir diese Folge nur einmal benötigen.
#3: Der String rgb enthält drei Zahlen zwischen 0 und 255 für die RGB-Farbanteile des
Pixels an der Position
(x, y), (zum Beispiel "255 0 0" für ein rotes Pixel.
#4: Der String wird gesplittet und in ein Tupel aus drei ganzen Zahlen umgewandelt.
#5: Zu jedem Farbwert bilden wir den komplementären Wert.
text="Laden",
command=self.__laden)
self.buttonNegativ = Button(master=self.fenster,
text="Negativ",
command=self.__invertieren)
def __layout(self):
self.bildflaeche.pack()
self.buttonLaden.pack(side=LEFT)
self.buttonNegativ.pack(side=LEFT)
def __laden (self):
pfad = filedialog.askopenfilename() #1
if pfad:
self.bild = PhotoImage(file=pfad)
self.bildflaeche.config(image=self.bild)
def __invertieren (self):
punkte = ((x,y) for x in range(self.bild.width())
for y in range(self.bild.height())) #2
for x, y in punkte:
rgb = self.bild.get(x, y) #3
r, g, b = map(int, rgb.split()) #4
r = 255 – r #5
g = 255 – g
b = 255 – b
rgb = "#{:02x}{:02x}{:02x}".format(r, g, b) #6
self.bild.put((rgb,), (x,y))
f = FotoViewer()

Get Python 3 - Lernen und professionell anwenden now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.