Fotobox - Photobooth

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Fhepfussel
User
Beiträge: 9
Registriert: Freitag 17. November 2017, 11:40

Hallo Python Fans,


danke für die Aufnahme in dieses Forum.


Ich habe erst vor kurzem angefangen mich mit der 2er Himbeere zu befassen. Das erste war der Retropi, aber spielen mochte ich nicht, also kam mir der Gedanke auf einer Hochzeit eine Fotobox zu basteln (Projekt von Bitbastelei). Soweit so gut, aber ich bräuchte da etwas Hilfe beim hinzufügen einer Beleuchtung. Das ganze ist in Python geschrieben, sieht auch für mich als Leie richtig gut aus, aber in ein bestehendes Skript etwas einzufügen ist doch was anderes. Vieleicht findet sich hier jemand der mir Helfen könnte. Habe auch schon etwas recherchiert aber noch nicht das Richtige gefunden. Der Ausgang ist im Skript schon vorgesehen.

Da in dem Programm ein Countdown nach Tastendruck abläuft hatte ich vor eine Lampe bei Cd <2 angehen zu lassen und bei Cd -1 wieder erlöschen zu lassen, damit das Bild relativ gut ausgeleuchtet ist.

Habe mehrere Versuche gestartet den GPIO Output 25 der im Skript schon vorgesehen ist zu schalten, aber bis jetzt ohne erfolg.

Würde gerne hier das Skript anhängen, aber wie?

Mit freundlichen Grüssen


Ralf
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du kannst das hier einkopieren. Aber dann Code-Tags nicht vergessen! Die findest du hier über der textbox als Dropdown-Menü oder in der Tollbar.

Am besten die Vorschau nutzen & schauen ob es richtig aussieht.
Fhepfussel
User
Beiträge: 9
Registriert: Freitag 17. November 2017, 11:40

Da ich absoluter Leie, was Programieren angeht, bin wusste ich nicht wie ich es einfügen muss. Das Programm ist auch immer hängengeblieben, keine Ahnung von einrücken, Position und ob das Format überhaupt stimmt. Oh habe gerade gesehen das meine Einträge gar nicht rot erscheinen, m..t. In Linie 115 wollte ich den Output einschalten und in Linie 141 wieder ausschalten.
Den Code den ich für die Fotobox benutzt habe war ja schon so weit fertig, ich habe nur versucht in dieser Datei etwas zu ändern damit ich am Pi eine Beleuchtung geschaltet bekomme. Meine Zeilen hab ich wieder gelöscht nachdem es nicht funktioniert hatte.

Grüsse Ralf



Code: Alles auswählen


import sys
import os
import subprocess
from datetime import datetime, date, time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QTime, QTimer
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QApplication, QDialog
from layout import Ui_Form
from shutil import copyfile, move
from stat import S_ISREG, ST_MTIME, ST_MODE
from picamera import PiCamera
import RPi.GPIO as GPIO
from time import sleep

class Ui_Form_mod(Ui_Form):

    ########### INIT

    def initTimer(self, Form):
        #Camera
        self.camera = PiCamera()
        self.isLive = False

        #Countdown Updater
        self.timerCnt = QTimer(Form)
        self.timerCnt.timeout.connect(self.updateCountdown)
        self.timerCnt.setSingleShot(True)

        #Blank dummy image
        self.blankImage = QPixmap(1,1)

        self.lastPhoto = ""
        self.screen = ""
        self.temp = "/tmp/fotobox/"
        self.saved = "/media/usb0/"

        if not os.path.exists(self.temp):
            os.makedirs(self.temp)
        if not os.path.exists(self.saved):
            os.makedirs(self.saved)

    def patchDesign(self, Form):
        Form.setWindowTitle("Fotobox")
        font = QtGui.QFont()
        font.setFamily("DejaVu Sans Mono")
        font.setPointSize(28)
        font.setBold(True)
        font.setWeight(75)
        self.l_btn1.setFont(font)
        self.l_btn2.setFont(font)
        self.l_btn3.setFont(font)

        self.footerTpl = "Fotobox Version 0.0.2 · created by: BitBastelei"

        Form.showFullScreen()

    ########### MAIN
    def screenMain(self):
        self.screen = 1
        #Show instructions
        self.instructions.setHtml("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Sans\'; font-size:17pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Hallo und willkommen in der Fotobox!</p>\n"
"<hr>"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Hier kannst du Fotos von dir und deinen Freunden machen!</p>\n"
"<hr>"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Drücke einfach auf den Knopf "Neues Foto" und los geht es!</p>"
"<hr>"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Du kannst die Fotos hier anschauen</p></body></html>")

        #Change buttons
        self.l_btn1.setText("Neues Foto ▶")
        self.l_btn2.setText("Fotobuch ▶")
        self.l_btn3.setText(" ")

        #start image update process
        if not self.isLive:
                self.image.setPixmap(self.blankImage)
                self.camera.start_preview(fullscreen=False, window = (0, 115, 960, 720))
                self.isLive = True

        #Reset footer
        self.label.setText(self.footerTpl)

    ########### CAPTURE

    def screenCapture(self):
        self.screen = 2
        #Change buttons
        font = QtGui.QFont()
        font.setFamily("DejaVu Sans Mono")
        font.setPointSize(28)
        font.setBold(True)
        font.setWeight(75)
        self.l_btn1.setFont(font)
        self.l_btn1.setText(" ")
        self.l_btn2.setText(" ")
        self.l_btn3.setText(" ")

        footer = self.footerTpl
        self.label.setText(footer)

        #start image update process
        if not self.isLive:
                self.image.setPixmap(self.blankImage)
                self.camera.start_preview(fullscreen=False, window = (0, 115, 960, 720))
                self.isLive = True

        #start countdown
        self.countdownTime = 4 #start at 3 seconds
        self.updateCountdown()

    #Countdown update
    def updateCountdown(self):
        self.countdownTime-=1 #I want my -- back :(

        instr = ("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Sans\'; font-size:17pt; font-weight:400; font-style:normal; text-align: center;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Los geht's!</p>\n"
"<hr>"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:220pt; \">")
        instr += str(self.countdownTime)
        instr += "</p></body></html>"

        self.instructions.setHtml(instr)
        if(self.countdownTime > 0):
            self.timerCnt.start(1000)
        else:
            self.photoTake()

    #Take photo
    def photoTake(self):
        if(self.isLive):
                self.camera.stop_preview()
                self.isLive=False

        self.lastPhoto = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + ".jpg"
        #@TODO Capture
        #copyfile(self.live, self.temp+self.lastPhoto)
        self.camera.capture(self.temp+self.lastPhoto)
        self.screenOK()

    def screenOK(self):
        self.screen = 3
        self.instructions.setHtml("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Sans\'; font-size:15pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Alles OK?</p>\n"
"<hr>"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Wenn ja drücke unten auf den passenden Knopf - dein Foto wird dann gespeichert und kann hier über das Fotobuch oder dein Handy angesehen werden.</p>\n"
"<hr>"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Grimasse doch zu schlimm? Drück auf "Neues Foto" und versuchs gleich nochmal</p></body></html>")


        #Change buttons
        self.l_btn1.setText("Speichern ▶")
        self.l_btn2.setText("Neues Foto ▶")
        self.l_btn3.setText("Abbruch ▶")

        #last image
        pixmap = QPixmap(self.temp+self.lastPhoto)
        pixmapS = pixmap.scaledToWidth(950)
        self.image.setPixmap(pixmapS)

        footer = self.footerTpl
        footer += " · Foto: "
        footer += self.lastPhoto
        self.label.setText(footer)

    def tempDel(self):
        if self.lastPhoto != "" and os.path.isfile(self.temp+self.lastPhoto):
            os.remove(self.temp+self.lastPhoto)
            self.lastPhoto = ""

    def noConfirm(self):
        self.tempDel()
        self.screenMain()

    def doConfirm(self):
        move(self.temp+self.lastPhoto, self.saved+self.lastPhoto)
        self.screenMain()

    def retry(self):
        self.tempDel()
        self.screenCapture()

    ########### VIEWER
    def startViewer(self):
        self.screen = 4
        if(self.isLive):
                self.camera.stop_preview()
                self.isLive = False

        #@TODO find last photo
        self.entries = None
        self.entries = (os.path.join(self.saved, fn) for fn in os.listdir(self.saved))
        self.entries = ((os.stat(path), path) for path in self.entries)
        self.entries = ((stat[ST_MTIME], path)
                   for stat, path in self.entries if S_ISREG(stat[ST_MODE]))
        self.entries = list(self.entries)

        if(len(self.entries) > 0):
            self.viewerIndex = len(self.entries)-1
            self.screenViewer()
        else:
            self.screenMain()

    def screenViewer(self):

        self.instructions.setHtml("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'Sans\'; font-size:15pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Hier sind die letzten Fotos der Veranstaltung</p>\n"
"<hr>"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Mit den Knöpfen unten kannst du dir andere Bilder anschauen oder zurück zur Aufnahme gehen.</p>\n"
"<hr>"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Du kannst die Fotos hier anschauen</p></body></html>")


        #Change buttons
        if(self.viewerIndex < (len(self.entries)-1)):
            self.l_btn1.setText("Nächstes ▶")
        else:
            self.l_btn1.setText(" ")
        if(self.viewerIndex > 0):
            self.l_btn2.setText("Letztes ▶")
        else:
            self.l_btn2.setText(" ")
        self.l_btn3.setText("Zurück ▶")

        #last image
        pixmap = QPixmap(str(self.entries[self.viewerIndex][1]))
        pixmapS = pixmap.scaledToWidth(950)
        self.image.setPixmap(pixmapS)

        footer = self.footerTpl
        footer += " · Foto: "
        footer += str(self.viewerIndex+1)
        footer += " von "
        footer += str(len(self.entries))
        footer += " · "
        footer += str(self.entries[self.viewerIndex][1])
        self.label.setText(footer)
    def viewPrev(self):
        print(self.viewerIndex)
        if(self.viewerIndex > 0):
            self.viewerIndex -= 1
        self.screenViewer()

    def viewNext(self):
        print(str((len(self.entries)-1)))
        print(self.viewerIndex)
        if(self.viewerIndex < (len(self.entries)-1)):
            self.viewerIndex += 1
        self.screenViewer()

class QDialog_mod(QDialog):
    def __init__(self):
        super(QDialog, self).__init__()
        self.ui = Ui_Form_mod()
        self.ui.setupUi(self)
        self.ui.initTimer(self)
        self.ui.patchDesign(self)
        self.ui.screenMain()

        GPIO.setmode(GPIO.BCM)

        GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.setup(25, GPIO.OUT)

        GPIO.output(25, 1) # GPIO25 auf 1
                
        self.btnC1 = GPIO.HIGH
        self.btnC2 = GPIO.HIGH
        self.btnC3 = GPIO.HIGH
        self.btnB  = 1

        #Key Poller
        self.timerKey = QTimer(self)
        self.timerKey.timeout.connect(self.buttonCheck)
        self.timerKey.start(25)

        self.show()

    def buttonCheck(self):
        if self.btnB == 0:
            if GPIO.input(17) != self.btnC1:
                self.btnB =3
                if GPIO.input(17) == GPIO.LOW:
                    self.buttonPress(1)
                self.btnC1 = GPIO.input(17)
            if GPIO.input(21) != self.btnC2:
                self.btnB = 3
                if GPIO.input(21) == GPIO.LOW:
                    self.buttonPress(2)
                self.btnC2 = GPIO.input(21)
            if GPIO.input(22) != self.btnC3:
                self.btnB = 3
                if GPIO.input(22) == GPIO.LOW:
                    self.buttonPress(3)
                self.btnC3 = GPIO.input(22)
        else:
            self.btnB -= 1

    #keyHandling
    def buttonPress(self, btn):
        if(self.ui.screen == 1):
            if(btn == 1):
                self.ui.screenCapture()
            elif(btn == 2):
                self.ui.startViewer()
        elif(self.ui.screen == 3):
            if(btn == 1):
                self.ui.doConfirm()
            elif(btn == 2):
                self.ui.retry()
            elif(btn == 3):
                self.ui.noConfirm()
        elif(self.ui.screen == 4):
            if(btn == 1):
                self.ui.viewNext()
            elif(btn == 2):
                self.ui.viewPrev()
            elif(btn == 3):
                self.ui.screenMain()

    #Emulation
    def keyPressEvent(self, e):
        if e.key() == QtCore.Qt.Key_Escape:
            self.close()
        elif e.key() == QtCore.Qt.Key_Q: #gimme switch/case -.-
            self.ui.screenMain()
        elif e.key() == QtCore.Qt.Key_W: #gimme switch/case -.-
            self.ui.screenCapture()
        elif e.key() == QtCore.Qt.Key_E: #@TODO viewer
            self.ui.startViewer()
        elif e.key() == QtCore.Qt.Key_Y: #@TODO save
            self.ui.doConfirm()
        elif e.key() == QtCore.Qt.Key_N: #@TODO abort
            self.ui.noConfirm()
        elif e.key() == QtCore.Qt.Key_R: #@TODO retry
            self.ui.retry()
        elif e.key() == QtCore.Qt.Key_K: #Left/Right is not passed
            self.ui.viewPrev()
        elif e.key() == QtCore.Qt.Key_L:
            self.ui.viewNext()
        elif e.key() == QtCore.Qt.Key_1:
            self.buttonPress(1)
        elif e.key() == QtCore.Qt.Key_2:
            self.buttonPress(2)
        elif e.key() == QtCore.Qt.Key_3:
            self.buttonPress(3)


app = QApplication(sys.argv)
window = QDialog_mod()

sys.exit(app.exec_())
Fhepfussel
User
Beiträge: 9
Registriert: Freitag 17. November 2017, 11:40

Hallo Forum,
ist den niemand da, der mir hierbei ein kleines bisschen helfen könnte?
Ich kenne mich leider mit Programmieren nicht so aus, was Computersprachen betrifft.
Wenn mir jemand zumindest zeigen würde was ich wo reinschreiben muss, wäre mir schon geholfen.
Er muss mir das Skript nicht komplett neu schreiben, nur zeigen was wo wie reinzuschreiben ist.
Natürlich hatte ich im vorfeld schon einige Beiträge gelesen, die mir nicht oder nur stellenweise geholfen haben.
Vielen dank im voraus.
Gruß Ralf
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst updateCountdown etwas manipulieren:

Code: Alles auswählen

def updateCountdown(self):
        GPIO.output(25, STOPZEIT <= self.countdownTime <= STARTZEIT)
        self.countdownTime-=1 #I want my -- back :(
Wobei du fuer STOPZEIT und STARTZEIT die Werte einsetzen musst, die du haben willst.
Fhepfussel
User
Beiträge: 9
Registriert: Freitag 17. November 2017, 11:40

Hallo __deets__,
danke für den Tip, werde ihn gleich mal ausprobieren.
Ergebnis folgt.
Danke gruß Ralf
Fhepfussel
User
Beiträge: 9
Registriert: Freitag 17. November 2017, 11:40

Also, habe für STARTZEIT 2 und für STOPZEIT 0 eingegeben.
Der Output geht bei 2s an, aber nicht mehr aus.????????
Ah, erst wenn ich ein neues Foto machen will geht der Output aus und bei 2s wieder an. So wollte ich das glaube ich nicht.
Aber schon mal ein vorteil das Programm stürzt nicht ab.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann setz doch mal stop auf 1.
Fhepfussel
User
Beiträge: 9
Registriert: Freitag 17. November 2017, 11:40

Ok, gesagt getan, aber das selbe Ergebnis wie zuvor. :shock:
Wenn der output wenigstens beim Drücken der Sperichern Taste ausgehen würde wäre es auch gut.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hm. Dann setz mal den GPIO auf False NACH dem self.photoTake() in der gleichen Methode. Einrückung beachten! Muss auf der gleichen Tiefe stehen wie das self.photoTake()
Fhepfussel
User
Beiträge: 9
Registriert: Freitag 17. November 2017, 11:40

@__deets__,
Super es scheint zu Funktionieren :D
Werde jetzt mal einen Dauertest machen, aber es scheint wirklich zu machen was es soll.
Vielen Dank, das war sehr lehr- und hilfreich.
Grüße Ralf

P.S.: Könnte man zum Ausschalten des Lichts noch eine Zeit von 1s dazumachen?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

@Ralf: koennte, aber das wird komplizierter weil ein neuer Timer gestartet werden muss. Und dazu hab' ich keine Lust :)
Fhepfussel
User
Beiträge: 9
Registriert: Freitag 17. November 2017, 11:40

Nee, war auch nur so ne Idee, funzt super bis jetzt.
Nochmal Danke für die Hilfe.
Gruß Ralf :D :D :D
Fhepfussel
User
Beiträge: 9
Registriert: Freitag 17. November 2017, 11:40

So nach umfangreichen Tests und das dazuschalten eins SSR's kann ich jetzt mit Beleuchtung arbeiten. Alles funktioniert sehr stabil, also kann ich mit dem Bau eines Gehäuses anfangen.
Habe mal mit einem 80W Halogenstrahler probiert, war aber nicht sehr schön (rotstichige Biler) von den Aufnahmen :? , danach noch mit 3W LED Lampen versucht und das Ergebnis hat mich mehr Überzeugt :D , also werde ich 2 LED Leuchten in das Gehäuse mit integrieren.

Danke für die Hilfe
Grüße Ralf
Antworten