ich hatte noch nie etwas mit Python zutun bis ich vor einer Woche angefangen habe mir eine FOTOBOX zubauen -> Anleitung von Youtube BitBastelei. Verwendet wird ein Raspberry Pi 3 + PiCamera V2 8MP
Mein Problem ist, dass die Fotos immer nur in der Auflösung vom Bildschirm (15Zoll 1024 x 768) gespeichert werden. Ich habe schon viel im Google gelesen und den Befehl camera.resolution = (2592 , 1944) versucht. Aber sobald dieser im Programm steht bleibt der Bildschirm schwarz.
Kann mir einer helfen? Benötigt werden 2 Python Dateien. 1x Layout.py (dort habe ich alles auf 15 Zoll angepasst) und dann das Hauptprogramm siehe unten.
Code: Alles auswählen
1 import sys
2 import os
3 import subprocess
4 from datetime import datetime, date, time
5 from PyQt5 import QtCore, QtGui, QtWidgets
6 from PyQt5.QtCore import QTime, QTimer
7 from PyQt5.QtGui import QIcon, QPixmap
8 from PyQt5.QtWidgets import QApplication, QDialog
9 from layout import Ui_Form
10 from shutil import copyfile, move
11 from stat import S_ISREG, ST_MTIME, ST_MODE
12 from picamera import PiCamera
13 import RPi.GPIO as GPIO
14 from time import sleep
15
16 class Ui_Form_mod(Ui_Form):
17
18 ########### INIT
19
20 def initTimer(self, Form):
21 #Camera
22 self.camera = PiCamera()
23 self.isLive = False
24
25 #Countdown Updater
26 self.timerCnt = QTimer(Form)
27 self.timerCnt.timeout.connect(self.updateCountdown)
28 self.timerCnt.setSingleShot(True)
29
30 #Blank dummy image
31 self.blankImage = QPixmap(1,1)
32
33 self.lastPhoto = ""
34 self.screen = ""
35 self.temp = "/tmp/fotobox/"
36 self.saved = "/media/usb0/"
37
38 if not os.path.exists(self.temp):
39 os.makedirs(self.temp)
40 if not os.path.exists(self.saved):
41 os.makedirs(self.saved)
42
43 def patchDesign(self, Form):
44 Form.setWindowTitle("Fotobox")
45 font = QtGui.QFont()
46 font.setFamily("DejaVu Sans Mono")
47 font.setPointSize(28)
48 font.setBold(True)
49 font.setWeight(75)
50 self.l_btn1.setFont(font)
51 self.l_btn2.setFont(font)
52 self.l_btn3.setFont(font)
53
54 self.footerTpl = "Fotobox Version 0.0.2 · sponsored by: BitBastelei · Reichelt Elektronik"
55
56 Form.showFullScreen()
57
58 ########### MAIN
59 def screenMain(self):
60 self.screen = 1
61 #Show instructions
62 self.instructions.setHtml("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
63 "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
64 "p, li { white-space: pre-wrap; }\n"
65 "</style></head><body style=\" font-family:\'Sans\'; font-size:17pt; font-weight:400; font-style:normal;\">\n"
66 "<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"
67 "<hr>"
68 "<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"
69 "<hr>"
70 "<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>"
71 "<hr>"
72 "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Du kannst du Fotos hier oder per Handy anschauen/runterladen: http://fotobox.ffmyk</p></body></html>")
73
74 #Change buttons
75 self.l_btn1.setText("Neues Foto ▶")
76 self.l_btn2.setText("Fotobuch ▶")
77 self.l_btn3.setText(" ")
78
79 #start image update process
80 if not self.isLive:
81 self.image.setPixmap(self.blankImage)
82 self.camera.start_preview(fullscreen=False, window = (0, 115, 960, 720))
83 self.isLive = True
84
85 #Reset footer
86 self.label.setText(self.footerTpl)
87
88 ########### CAPTURE
89
90 def screenCapture(self):
91 self.screen = 2
92 #Change buttons
93 font = QtGui.QFont()
94 font.setFamily("DejaVu Sans Mono")
95 font.setPointSize(28)
96 font.setBold(True)
97 font.setWeight(75)
98 self.l_btn1.setFont(font)
99 self.l_btn1.setText(" ")
100 self.l_btn2.setText(" ")
101 self.l_btn3.setText(" ")
102
103 footer = self.footerTpl
104 self.label.setText(footer)
105
106 #start image update process
107 if not self.isLive:
108 self.image.setPixmap(self.blankImage)
109 self.camera.start_preview(fullscreen=False, window = (0, 115, 960, 720))
110 self.isLive = True
111
112 #start countdown
113 self.countdownTime = 4 #start at 3 seconds
114 self.updateCountdown()
115
116 #Countdown update
117 def updateCountdown(self):
118 self.countdownTime-=1 #I want my -- back :(
119
120 instr = ("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
121 "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
122 "p, li { white-space: pre-wrap; }\n"
123 "</style></head><body style=\" font-family:\'Sans\'; font-size:17pt; font-weight:400; font-style:normal; text-align: center;\">\n"
124 "<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"
125 "<hr>"
126 "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:220pt; \">")
127 instr += str(self.countdownTime)
128 instr += "</p></body></html>"
129
130 self.instructions.setHtml(instr)
131 if(self.countdownTime > 0):
132 self.timerCnt.start(1000)
133 else:
134 self.photoTake()
135
136 #Take photo
137 def photoTake(self):
138 if(self.isLive):
139 self.camera.stop_preview()
140 self.isLive=False
141
142 self.lastPhoto = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + ".jpg"
143 #@TODO Capture
144 #copyfile(self.live, self.temp+self.lastPhoto)
145 self.camera.capture(self.temp+self.lastPhoto)
146 self.screenOK()
147
148 def screenOK(self):
149 self.screen = 3
150 self.instructions.setHtml("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
151 "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
152 "p, li { white-space: pre-wrap; }\n"
153 "</style></head><body style=\" font-family:\'Sans\'; font-size:15pt; font-weight:400; font-style:normal;\">\n"
154 "<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"
155 "<hr>"
156 "<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"
157 "<hr>"
158 "<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>")
159
160
161 #Change buttons
162 self.l_btn1.setText("Speichern ▶")
163 self.l_btn2.setText("Neues Foto ▶")
164 self.l_btn3.setText("Abbruch ▶")
165
166 #last image
167 pixmap = QPixmap(self.temp+self.lastPhoto)
168 pixmapS = pixmap.scaledToWidth(950)
169 self.image.setPixmap(pixmapS)
170
171 footer = self.footerTpl
172 footer += " · Foto: "
173 footer += self.lastPhoto
174 self.label.setText(footer)
175
176 def tempDel(self):
177 if self.lastPhoto != "" and os.path.isfile(self.temp+self.lastPhoto):
178 os.remove(self.temp+self.lastPhoto)
179 self.lastPhoto = ""
180
181 def noConfirm(self):
182 self.tempDel()
183 self.screenMain()
184
185 def doConfirm(self):
186 move(self.temp+self.lastPhoto, self.saved+self.lastPhoto)
187 self.screenMain()
188
189 def retry(self):
190 self.tempDel()
191 self.screenCapture()
192
193 ########### VIEWER
194 def startViewer(self):
195 self.screen = 4
196 if(self.isLive):
197 self.camera.stop_preview()
198 self.isLive = False
199
200 #@TODO find last photo
201 self.entries = None
202 self.entries = (os.path.join(self.saved, fn) for fn in os.listdir(self.saved))
203 self.entries = ((os.stat(path), path) for path in self.entries)
204 self.entries = ((stat[ST_MTIME], path)
205 for stat, path in self.entries if S_ISREG(stat[ST_MODE]))
206 self.entries = list(self.entries)
207
208 if(len(self.entries) > 0):
209 self.viewerIndex = len(self.entries)-1
210 self.screenViewer()
211 else:
212 self.screenMain()
213
214 def screenViewer(self):
215
216 self.instructions.setHtml("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
217 "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
218 "p, li { white-space: pre-wrap; }\n"
219 "</style></head><body style=\" font-family:\'Sans\'; font-size:15pt; font-weight:400; font-style:normal;\">\n"
220 "<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"
221 "<hr>"
222 "<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"
223 "<hr>"
224 "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Du kannst du Fotos hier oder per Handy anschauen/runterladen:<br>http://fotobox.ffmyk</p></body></html>")
225
226
227 #Change buttons
228 if(self.viewerIndex < (len(self.entries)-1)):
229 self.l_btn1.setText("Nächstes ▶")
230 else:
231 self.l_btn1.setText(" ")
232 if(self.viewerIndex > 0):
233 self.l_btn2.setText("Letztes ▶")
234 else:
235 self.l_btn2.setText(" ")
236 self.l_btn3.setText("Zurück ▶")
237
238 #last image
239 pixmap = QPixmap(str(self.entries[self.viewerIndex][1]))
240 pixmapS = pixmap.scaledToWidth(950)
241 self.image.setPixmap(pixmapS)
242
243 footer = self.footerTpl
244 footer += " · Foto: "
245 footer += str(self.viewerIndex+1)
246 footer += " von "
247 footer += str(len(self.entries))
248 footer += " · "
249 footer += str(self.entries[self.viewerIndex][1])
250 self.label.setText(footer)
251 def viewPrev(self):
252 print(self.viewerIndex)
253 if(self.viewerIndex > 0):
254 self.viewerIndex -= 1
255 self.screenViewer()
256
257 def viewNext(self):
258 print(str((len(self.entries)-1)))
259 print(self.viewerIndex)
260 if(self.viewerIndex < (len(self.entries)-1)):
261 self.viewerIndex += 1
262 self.screenViewer()
263
264 class QDialog_mod(QDialog):
265 def __init__(self):
266 super(QDialog, self).__init__()
267 self.ui = Ui_Form_mod()
268 self.ui.setupUi(self)
269 self.ui.initTimer(self)
270 self.ui.patchDesign(self)
271 self.ui.screenMain()
272
273 GPIO.setmode(GPIO.BCM)
274
275 GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
276 GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
277 GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP)
278 GPIO.setup(25, GPIO.OUT)
279
280 self.btnC1 = GPIO.HIGH
281 self.btnC2 = GPIO.HIGH
282 self.btnC3 = GPIO.HIGH
283 self.btnB = 1
284
285 #Key Poller
286 self.timerKey = QTimer(self)
287 self.timerKey.timeout.connect(self.buttonCheck)
288 self.timerKey.start(25)
289
290 self.show()
291
292 def buttonCheck(self):
293 if self.btnB == 0:
294 if GPIO.input(17) != self.btnC1:
295 self.btnB =3
296 if GPIO.input(17) == GPIO.LOW:
297 self.buttonPress(1)
298 self.btnC1 = GPIO.input(17)
299 if GPIO.input(21) != self.btnC2:
300 self.btnB = 3
301 if GPIO.input(21) == GPIO.LOW:
302 self.buttonPress(2)
303 self.btnC2 = GPIO.input(21)
304 if GPIO.input(22) != self.btnC3:
305 self.btnB = 3
306 if GPIO.input(22) == GPIO.LOW:
307 self.buttonPress(3)
308 self.btnC3 = GPIO.input(22)
309 else:
310 self.btnB -= 1
311
312 #keyHandling
313 def buttonPress(self, btn):
314 if(self.ui.screen == 1):
315 if(btn == 1):
316 self.ui.screenCapture()
317 elif(btn == 2):
318 self.ui.startViewer()
319 elif(self.ui.screen == 3):
320 if(btn == 1):
321 self.ui.doConfirm()
322 elif(btn == 2):
323 self.ui.retry()
324 elif(btn == 3):
325 self.ui.noConfirm()
326 elif(self.ui.screen == 4):
327 if(btn == 1):
328 self.ui.viewNext()
329 elif(btn == 2):
330 self.ui.viewPrev()
331 elif(btn == 3):
332 self.ui.screenMain()
333
334 #Emulation
335 def keyPressEvent(self, e):
336 if e.key() == QtCore.Qt.Key_Escape:
337 self.close()
338 elif e.key() == QtCore.Qt.Key_Q: #gimme switch/case -.-
339 self.ui.screenMain()
340 elif e.key() == QtCore.Qt.Key_W: #gimme switch/case -.-
341 self.ui.screenCapture()
342 elif e.key() == QtCore.Qt.Key_E: #@TODO viewer
343 self.ui.startViewer()
344 elif e.key() == QtCore.Qt.Key_Y: #@TODO save
345 self.ui.doConfirm()
346 elif e.key() == QtCore.Qt.Key_N: #@TODO abort
347 self.ui.noConfirm()
348 elif e.key() == QtCore.Qt.Key_R: #@TODO retry
349 self.ui.retry()
350 elif e.key() == QtCore.Qt.Key_K: #Left/Right is not passed
351 self.ui.viewPrev()
352 elif e.key() == QtCore.Qt.Key_L:
353 self.ui.viewNext()
354 elif e.key() == QtCore.Qt.Key_1:
355 self.buttonPress(1)
356 elif e.key() == QtCore.Qt.Key_2:
357 self.buttonPress(2)
358 elif e.key() == QtCore.Qt.Key_3:
359 self.buttonPress(3)
360
361
362 app = QApplication(sys.argv)
363 window = QDialog_mod()
364
365 sys.exit(app.exec_())