Ich möchte nun einfach mal mein Projekt etwas vorstellen evtl. kann ja jemand davon etwas gebrauchen oder sich zumindest anregungen für ein Eigenes Projekt holen.
Um es auch gleich vorweg zu nehmen, dies ist mein erstes Projekt in Python, der Code ist also mit sicherheit alles andere als schön.
Ich hoffe jedoch dies mit eurer Hilfe zu verbessern.
Ausgeführt wird das Projekt auf einem Raspberry-Py mit Raspbian.
Der Funktionsablauf soll ungefähr folgender sein:
- Der Raspberry ist auf Stand-by und wartet auf den Start vom User über GPIO
- Anschließend triggert der Pi via GPIO 4 Fotos
- Sind die Fotos im Kasten baue ich mittels PIL eine Art Collage aus den Aufnahmen
- Nun Soll der User Gelegenheit Bekommen zu der Collage noch einen Persönlichen text hinzu zu fügen
- Der User kann nun über eine Button eine Vorschau der fertigen Collage ansehen oder
- Über eine zweiten Button die Bearbeitung abschließen und die fertige Collage abspeichern
- Danach werden alle bisherigen Werke in Zufälliger Reihenfolge angezeigt und der Raspberry geht parallel wieder zurück auf Anfang und wartet auf den nächsten Trigger
Momentan stecke ich daran fest, Informationen an die Button-Events zu übergeben.
Diese rufe ich ja nicht direkt auf (mit Übergabeparameter und Co.), wie macht man das da?
Dem einen oder anderen dürfte das Projekt schon bekannt vorkommen
Ich habe auch versucht eure Ratschläge aus anderen Beiträgen so gut ich kann umzusetzen.
Leider bekomme ich es noch immer nicht hin, die "bösen global" komplett zu eliminieren.
Könnte mir da evtl. jemand sagen, wie ich es besser machen könnte?
Hier mal der komplette code:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
##########################################################################################################
#
# Script zum anordnen mehrerer Bilder in einem vorgegebenen Schema
# Written by Michael Zeller zeller-michael(at)gmx.net 2015-02-10
#
##########################################################################################################
# Import of librarys
#--------------------------------------------------------------------------------------------------
# Externe Module / librarys laden
from Tkinter import *
from os import *
from PIL import Image, ImageDraw, ImageFont, ImageTk
try:
import RPi.GPIO as GPIO
except RuntimeError:
print("Error importing RPi.GPIO! This is probably because you need superuser privileges. You can achieve this by using 'sudo' to run your script")
import time
import glob
# Projekt Einstellungen:
#--------------------------------------------------------------------------------------------------
# Positionen der Bilder. Angaben in Pixel von der oberen linken Ecke des Hintergrundes bemessen
# Aufbau Array: PildPos 1,2,3,4 und TextPos
ImgPositions = [(15,15),(15,796),(350,796),(700,796),(1200, 400)]
# Groessen auf die die Bilder skaliert werden sollen. Angaben in Pixel Breite,Hoehe
# Nur zwei verschiedene bildergroessen, da die Bilder 2 bis 4 gleich gross sein sollen
ImgSizes = [(1150, 768),(617, 375)]
# Verzeichnisse
font = ImageFont.truetype("/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf",40)
PictureSource = "/home/pi/Desktop/FotoBox/EingangsBilder/" # Die Speicherkarte der angeschlossenen Kammera
Collagen = "/home/pi/Desktop/FotoBox/Collagen/"
VerarbeiteteBilder = "/home/pi/Desktop/FotoBox/VerarbeiteteBilder/"
Background = Image.open("Hintergrund_1.png")
# Belegung der GPIO
triggerInPin = 11
triggerOutPin = 13
pictureCount = 0
# use the Board-numbering to identify the GPIO signals
GPIO.setmode(GPIO.BOARD)
# HW-Initalisation
#--------------------------------------------------------------------------------------------------
GPIO.setup(triggerInPin, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.setup(triggerOutPin, GPIO.OUT)
##########################################################################################################
# Funktionen:
##########################################################################################################
# ISR (Interrupt routine)
#--------------------------------------------------------------------------------------------------
def Interrupt(channel):
oneCycle(ImgPositions, ImgSizes, PictureSource, Background)
# Button Event "Preview":
#--------------------------------------------------------------------------------------------------
def callbackPreview():
global Background
global ImgPositions
print "Button event Preview"
BackgroundDummy = Background.copy()
# Text auf dem Hintergund platzieren
draw = ImageDraw.Draw(BackgroundDummy)
draw.text(ImgPositions[4], TextBoxDedication.get("1.0",END), font=font)
BackgroundDummy = BackgroundDummy.resize(ImgSize1)
photo = ImageTk.PhotoImage(BackgroundDummy)
LabelPreview = Label(window, height=768, width=1150, background="#F10", foreground="#F10", image=photo)
LabelPreview.image = photo
LabelPreview.grid(row=0, columnspan=3)
# Button Event "Complete":
#--------------------------------------------------------------------------------------------------
def callbackComplete():
global Background
global ImgPositions
global Collagen
print "Button event Complete"
# Text auf dem Hintergund platzieren
draw = ImageDraw.Draw(Background)
draw.text(ImgPositions[4], TextBoxDedication.get("1.0",END), font=font)
Background.save(Collagen + time.strftime("%d.%m.%Y_%H:%M:%S") + "_" + TextBoxPersons.get("1.0",END) + ".jpg", "JPEG")
window.destroy()
# Funktion für einen Programmablauf
#--------------------------------------------------------------------------------------------------
def oneCycle(myImgPositions, myImgSizes, myPictureSource, myBackground):
pictureCount = 0
time.sleep(2)
while pictureCount < 4:
GPIO.output(triggerOutPin,GPIO.HIGH)
time.sleep(1)
GPIO.output(triggerOutPin,GPIO.LOW)
pictureCount = pictureCount + 1
print "Bild Nr.: " + str(pictureCount) + " geschossen"
time.sleep(2)
time.sleep(2)
EingangsBilder = glob.glob(myPictureSource + "*.JPG") # ! Case-Sensitive bei Dateiendung
print "Die Eingangsbilder:"
for filename in EingangsBilder:
print filename
# Aufbereitung der einzelnen Biler
# Öffnen der Bilder
Img1 = Image.open(EingangsBilder[0]) # grosses bild links Oben
Img2 = Image.open(EingangsBilder[1]) # kleines Bild unten links
Img3 = Image.open(EingangsBilder[2]) # kleines Bild unten mitte
Img4 = Image.open(EingangsBilder[3]) # kleines Bild unten rechts
# Resize
Img1 = Img1.resize(myImgSizes[0])
Img2 = Img2.resize(myImgSizes[1])
Img3 = Img3.resize(myImgSizes[1])
Img4 = Img4.resize(myImgSizes[1])
# Platzierung der Bilder auf dem Hintergrund
Background.paste(Img1, myImgPositions[0])
Background.paste(Img2, myImgPositions[1])
Background.paste(Img3, myImgPositions[2])
Background.paste(Img4, myImgPositions[3])
# Dateien wieder schließen
#Img1.close()
#Img2.close()
#Img3.close()
#Img4.close()
print "Resized und zusammengebaut"
##########################################################################################################
# GUI erzeugen
window=Tk()
window.title('Geburtstags-Fotoerinnerungen-Box')
# folgende zwei zeilen für Fenserdarstellung (nicht vollbild)
#window.geometry('900x500') # Breite mal Hoehe vom window, Einheit: Pixel
#window.resizable(width=None, height=None)
window.attributes("-fullscreen", True) # Öffnet das Fenster im vollbildmodus
# Label zur anzeige des Bildes erzeugen
photo = ImageTk.PhotoImage(Background.resize(myImgSizes[0]))
LabelPreview = Label(window, height=768, width=1150, background="#F10", foreground="#F10", image=photo)
LabelPreview.image = photo
LabelPreview.grid(row=0, columnspan=3)
# Label Glückwünsche erzeugen
LabelDedication = Label(window, height=2, width=30, bd=1, font=("Comic_Sans_MS", 16))
LabelDedication.configure(text="Deine/Eure besten Wünsche \n an das Geburtstagskind:")
LabelDedication.grid(row=1, column=0)
# Textfeld erzeugen
TextBoxDedication = Text(window, height=10, width=30, font=("Comic_Sans_MS", 16))
TextBoxDedication.grid(row=2, column=0, rowspan=2)
TextBoxDedication.insert(END, "")
# Label Personen erzeugen
LabelPersons = Label(window, height=2, width=30, font=("Comic_Sans_MS", 16))
LabelPersons.configure(text="Wer ist alles auf dem Bild?:")
LabelPersons.grid(row=1, column=1)
# Textfeld erzeugen
TextBoxPersons = Text(window, height=10, width=30, font=("Comic_Sans_MS", 16), takefocus=TRUE)
TextBoxPersons.grid(row=2, column=1, rowspan=2)
TextBoxPersons.insert(END, "")
# Button preview erzeugen
ButtonPreview = Button(window, text="Vorschau", command=callbackPreview)
ButtonPreview.grid(row=2, column=2)
# Button complete erzeugen
ButtonComplete = Button(window, text="Go", command=callbackComplete)
ButtonComplete.grid(row=3, column=2)
# Dateien aus dem Eingangs in den Ausgangsordner verschieben
for filename in EingangsBilder:
EinBild = filename
AusBild = filename.replace("EingangsBilder", "VerarbeiteteBilder")
print EinBild
print AusBild
# rename(EinBild, AusBild) #Nur zum Testen Auskommentiert, da das Verschieben der Bilder lästig wurde... ;)
print "Bilder verschoben"
window.mainloop()
print "after window.mainloop"
return
# Interrupt Event hinzufuegen. Pin 17, auf steigende Flanke reagieren und ISR "Interrupt" deklarieren
GPIO.add_event_detect(triggerInPin, GPIO.RISING, callback = Interrupt, bouncetime = 1000)
# Endlosschleife
while True:
time.sleep(1)
viele Grüße
DaZeller
PS: Bitte geht nicht zu hart mit mir in's Gericht, ich versuche wirklich dazu zu lernen und es ist nunmal noch kein Meister vom Himmel gefallen.
EDIT:
Um das Problem an dem im momentan hänge besser zu verdeutlichen hier die Ausgabe der Konsole:
Code: Alles auswählen
pi@FotoBoxPi ~/Desktop/FotoBox $ sudo python PythonCollage_8.py
PythonCollage_8.py:48: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
GPIO.setup(triggerOutPin, GPIO.OUT)
Bild Nr.: 1 geschossen
Bild Nr.: 2 geschossen
Bild Nr.: 3 geschossen
Bild Nr.: 4 geschossen
Die Eingangsbilder:
/home/pi/Desktop/FotoBox/EingangsBilder/sticky-notes.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/wasser2.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/IMG_3301.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/IMG_3358.JPG
Resized und zusammengebaut
/home/pi/Desktop/FotoBox/EingangsBilder/sticky-notes.JPG
/home/pi/Desktop/FotoBox/VerarbeiteteBilder/sticky-notes.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/wasser2.JPG
/home/pi/Desktop/FotoBox/VerarbeiteteBilder/wasser2.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/IMG_3301.JPG
/home/pi/Desktop/FotoBox/VerarbeiteteBilder/IMG_3301.JPG
/home/pi/Desktop/FotoBox/EingangsBilder/IMG_3358.JPG
/home/pi/Desktop/FotoBox/VerarbeiteteBilder/IMG_3358.JPG
Bilder verschoben
Button event Preview
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1437, in __call__
return self.func(*args)
File "PythonCollage_8.py", line 71, in callbackPreview
draw.text(ImgPositions[4], TextBoxDedication.get("1.0",END), font=font)
NameError: global name 'TextBoxDedication' is not defined
Button event Complete
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1437, in __call__
return self.func(*args)
File "PythonCollage_8.py", line 91, in callbackComplete
draw.text(ImgPositions[4], TextBoxDedication.get("1.0",END), font=font)
NameError: global name 'TextBoxDedication' is not defined
after window.mainloop
Bild Nr.: 1 geschossen
Bild Nr.: 2 geschossen
^CBild Nr.: 3 geschossen
Traceback (most recent call last):
File "PythonCollage_8.py", line 197, in <module>
time.sleep(1)
KeyboardInterrupt