From c6e6fd369c674e364b00eae77fdb6da724b49894 Mon Sep 17 00:00:00 2001 From: Weber Date: Thu, 19 Sep 2019 12:08:39 +0200 Subject: [PATCH 1/4] My changes and extensions to new codebas added --- PBlogo.png | Bin 0 -> 27594 bytes photobooth/camera/CameraPicamera.py | 3 + photobooth/camera/PictureDimensions.py | 27 +- photobooth/camera/__init__.py | 244 +++++++++++++++++- photobooth/defaults.cfg | 30 ++- photobooth/gui/Qt5Gui/Frames.py | 107 +++++++- photobooth/gui/Qt5Gui/__init__.py | 1 + .../gui/Qt5Gui/stylesheets/dark-800x600.qss | 8 +- .../gui/Qt5Gui/stylesheets/dark_small.qss | 239 +++++++++++++++++ photobooth/worker/__init__.py | 5 +- 10 files changed, 629 insertions(+), 35 deletions(-) create mode 100644 PBlogo.png create mode 100644 photobooth/gui/Qt5Gui/stylesheets/dark_small.qss diff --git a/PBlogo.png b/PBlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..b012d6308c99b5ea5c29bddc8c44b121ef56f067 GIT binary patch literal 27594 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 literal 0 HcmV?d00001 diff --git a/photobooth/camera/CameraPicamera.py b/photobooth/camera/CameraPicamera.py index 0622b882..731a7b9f 100644 --- a/photobooth/camera/CameraPicamera.py +++ b/photobooth/camera/CameraPicamera.py @@ -49,6 +49,8 @@ def setActive(self): if self._cap is None or self._cap.closed: self._cap = PiCamera() + self._cap.resolution = (2352, 1568) # websta added because default is screen resolution + self._cap.framerate = 15 # websta added def setIdle(self): @@ -60,6 +62,7 @@ def getPreview(self): self.setActive() stream = io.BytesIO() + self._preview_resolution = (400,240) # websta added because preview is crap self._cap.capture(stream, format='jpeg', use_video_port=True, resize=self._preview_resolution) stream.seek(0) diff --git a/photobooth/camera/PictureDimensions.py b/photobooth/camera/PictureDimensions.py index 8cbd6ad7..a6f0e4a4 100644 --- a/photobooth/camera/PictureDimensions.py +++ b/photobooth/camera/PictureDimensions.py @@ -40,6 +40,8 @@ def __init__(self, config, capture_size): self._skip = [i for i in config.getIntList('Picture', 'skip') if 1 <= i and i <= self._num_pictures[0] * self._num_pictures[1]] + + logging.info('_skip: "{}"'.format(self._skip)) self.computeThumbnailDimensions() @@ -71,21 +73,29 @@ def computeThumbnailDimensions(self): thumb_dist = tuple(self._computeThumbOffset(i, inner_size[i]) for i in range(2)) - thumbs = [i for i in range(self.numPictures[0] * self.numPictures[1]) + self._thumbs = [i for i in range(self.numPictures[0] * self.numPictures[1]) #websta added self._ if i + 1 not in self._skip] self._thumb_offsets = [] - for i in thumbs: + #websta changedfrom thumbs + for i in range(self.numPictures[0] * self.numPictures[1]): pos = (i % self.numPictures[0], i // self.numPictures[0]) - self._thumb_offsets.append(tuple(border[j] + - (pos[j] + 1) * thumb_dist[j] + - pos[j] * self.thumbnailSize[j] + #self._thumb_offsets.append(tuple(border[j] + (pos[j] + 1) * thumb_dist[j] + pos[j] * self.thumbnailSize[j] for j in range(2))) + # websta: changed to calculate from center of image so the spacing is horizontally and vertically equal + thumb_offs = [] + for j in range(2): + if pos[j] < 1 : + thumb_offs.append(self.outputSize[j]//2 - self.thumbnailSize[j] - (thumb_dist[1] // 2)) + else : + thumb_offs.append(self.outputSize[j]//2 + (thumb_dist[1] // 2)) + + self._thumb_offsets.append(tuple(thumb_offs[j] for j in range(2))) logging.debug(('Assembled picture will contain {} ({}x{}) pictures ' 'in positions {}').format(self.totalNumPictures, self.numPictures[0], - self.numPictures[1], thumbs)) + self.numPictures[1], self._thumbs)) def computePreviewDimensions(self, config): @@ -103,6 +113,11 @@ def numPictures(self): return self._num_pictures + @property # added property thumbslocation + def thumbsLocation(self): + + return self._thumbs + @property def totalNumPictures(self): diff --git a/photobooth/camera/__init__.py b/photobooth/camera/__init__.py index 2f1ba1f2..c2bf3c0b 100644 --- a/photobooth/camera/__init__.py +++ b/photobooth/camera/__init__.py @@ -21,6 +21,7 @@ from PIL import Image, ImageOps from io import BytesIO +import math from .PictureDimensions import PictureDimensions from .. import StateMachine @@ -56,7 +57,9 @@ def __init__(self, config, comm, CameraModule): rot_vals = {0: None, 90: Image.ROTATE_90, 180: Image.ROTATE_180, 270: Image.ROTATE_270} self._rotation = rot_vals[self._cfg.getInt('Camera', 'rotation')] - + self._fancy = self._cfg.getBool('Picture', 'fancy') + logging.info('fancy "{}"'.format(self._fancy)) + def startup(self): self._cap = self._cam() @@ -70,15 +73,27 @@ def startup(self): self._pic_dims = PictureDimensions(self._cfg, test_picture.size) self._is_preview = self._is_preview and self._cap.hasPreview + self._logo_rot = self._cfg.getInt('Picture', 'logo_rot') + self._addlogo = self._cfg.getBool('Picture', 'addlogo') + logging.info('Adding Logo : "{}"'.format(self._addlogo)) + + logo_file = self._cfg.get('Picture', 'logo') + if len(logo_file) > 0: + logging.info('Using logo "{}"'.format(logo_file)) + self._logo = logo_file + else: + self._logo = Image.new('RGBA', (500,500),(155,0,0,0)) background = self._cfg.get('Picture', 'background') - if len(background) > 0: + addBg = self._cfg.getBool('Picture', 'addBg') + bgColor = self._cfg.get('Picture', 'bgColor') + if len(background) > 0 and addBg == True: logging.info('Using background "{}"'.format(background)) bg_picture = Image.open(background) - self._template = bg_picture.resize(self._pic_dims.outputSize) + self._template = bg_picture.resize(self._pic_dims.outputSize) #websta911 eventually add: ,Image.ANTIALIAS else: - self._template = Image.new('RGB', self._pic_dims.outputSize, - (255, 255, 255)) + bgCol = tuple(int(bgColor[i:i+2], 16) for i in (0, 2, 4)) + self._template = Image.new('RGB', self._pic_dims.outputSize,(bgCol)) self.setIdle() self._comm.send(Workers.MASTER, StateMachine.CameraEvent('ready')) @@ -160,7 +175,7 @@ def capturePicture(self, state): self._comm.send(Workers.MASTER, StateMachine.CameraEvent('assemble')) - def assemblePicture(self): + def assemblePicture_original(self): self.setIdle() @@ -170,6 +185,223 @@ def assemblePicture(self): resized = shot.resize(self._pic_dims.thumbnailSize) picture.paste(resized, self._pic_dims.thumbnailOffset[i]) + byte_data = BytesIO() + picture.save(byte_data, format='jpeg') + self._comm.send(Workers.MASTER, + StateMachine.CameraEvent('review', byte_data)) + self._pictures = [] + + def assemblePicture(self): + """my custom Version of assembling Pictures""" + self.setIdle() + + picture = self._template.copy() + if(self._fancy): + if(self._pic_dims.totalNumPictures == 3): + # ----- 3 pictures rotated------ + outer_border = 30 + inner_border = 30 + pic_rotation = 11 + + largePics_size = ( int( (self._pic_dims.outputSize[0] - ( outer_border *4)) // 10)*4.6 , + int( (self._pic_dims.outputSize[1] - ( outer_border *4 ) )//10)*4.6) + evenlargerPics_size = ( int( (self._pic_dims.outputSize[0] - ( outer_border *4)) // 10)*5.5 , + int( (self._pic_dims.outputSize[1] - ( outer_border *4 ) )//10)*5.5) + logo_size = ( int( (self._pic_dims.outputSize[0] ) //3 ), + int( (self._pic_dims.outputSize[1])//2 ) ) + #logo_size = (1206, 2669) #for hardcoded use + logging.info('size largePicx "{}"'.format(largePics_size)) + logging.info('Size logo "{}"'.format(logo_size)) + + # Image 0 + img = Image.open(self._pictures[0]) + img = img.convert('RGBA') + img.thumbnail(largePics_size) + logging.info('Image0 inserted with size pre rotation "{}"'.format(img.size)) + img = img.rotate(pic_rotation, expand=True) + offset = ( outer_border , + outer_border ) + picture.paste(img, offset, img) + logging.info('Image0 inserted with size "{}"'.format(img.size)) + logging.info('largepic size "{}"'.format(largePics_size)) + + # Image 1 + img = Image.open(self._pictures[1]) + img = img.convert('RGBA') + img.thumbnail(largePics_size) + img_norotated = img.size + img_norotated_small = img.size + img = img.rotate(pic_rotation, expand=True) + img_small = img + ta = (img_norotated[1]+outer_border) * math.cos(math.radians(90 - pic_rotation)) ## a = Hypothenuse c * cosinus(beta), beta = 90° - Alpha + tb = math.sqrt(img_norotated[1] ** 2 - ta ** 2) #b = sqrt(c² - a²) + logging.info('tb "{}"'.format(tb)) + logging.info('ta "{}"'.format(ta)) + logging.info('ta "{}"'.format((outer_border - round(ta)))) + #offset = ( (outer_border + round(ta)), + #(self._pic_dims.outputSize[1] - outer_border - img.size[1]) ) #b = sqrt(c² - a²) + #offset = ( ((self._pic_dims.outputSize[0] - outer_border*2 ) //2) - img.size[0], + #self._pic_dims.outputSize[1] - outer_border - img.size[1] ) + offset = ((outer_border + round(ta)), + (outer_border + round(tb) + outer_border )) + img_small_offset = offset + picture.paste(img, offset, img) + logging.info('Image1 inserted with size "{}"'.format(img.size)) + + # Image 2 + img = Image.open(self._pictures[2]) + img = img.convert('RGBA') + img.thumbnail(evenlargerPics_size) + img_norotated = img.size + img = img.rotate(pic_rotation, expand=True) + img_large = img + #ta = (img_norotated_small[1]) * math.cos(math.radians(90 - pic_rotation)) + #ta_d = outer_border * math.cos(math.radians(90 - pic_rotation)) + #tb_d = math.sqrt(outer_border ** 2 - ta_d ** 2) + #tta = outer_border * math.tan(math.radians(90 - pic_rotation)) + #tta_c = math.sqrt(tta ** 2 + outer_border ** 2) + + da = img_norotated[0] * math.cos(math.radians(90 - pic_rotation)) # a calculate a of current picture to get distante from left upper corner of img + tda = da * math.tan(90 - pic_rotation) + + #logging.info('ta_d "{}"'.format(ta_d)) + #logging.info('tb_d "{}"'.format(tb_d)) + #logging.info('ta "{}"'.format(ta)) + # offset = ( img.size[0] - round(ta) + outer_border * 2 + round(tb_d) , ##original + #offset = ( img.size[0] - round(ta) + outer_border * 2 , ##working somehow use that in case of not knowing + offset = ( img_small.size[0] - round(ta) + round(tda) , + outer_border ) + #offset = ( (self._pic_dims.outputSize[0] - outer_border *2 ) //2, + #outer_border ) + img_large_offset = offset + picture.paste(img, offset, img) + logging.info('Image2 inserted') + + #Logo + if(self._addlogo): + if len(self._logo) > 0: + logging.info('Using logo "{}"'.format(self._logo)) + logo = Image.open(self._logo).convert("RGBA") + logo = logo.rotate(self._logo_rot, expand=True) + logo.thumbnail(logo_size, Image.ANTIALIAS) + #offset = (self._pic_dims.outputSize[0] - outer_border - logo.size[0] , + #self._pic_dims.outputSize[1] - outer_border- logo.size[1] ) + rest_space = (((self._pic_dims.outputSize[0]-(img_small_offset[0] + img_small.size[0] + logo.size[0]))//2) , + ((self._pic_dims.outputSize[1]-(img_large_offset[1]+img_large.size[1]+logo.size[1]))//2)) + offset = (img_small_offset[0] + img_small.size[0] + rest_space[0] , + img_large_offset[1]+img_large.size[1] + rest_space[1]) + logging.info('Logo offset"{}"'.format(offset)) + picture.paste(logo,offset,logo) + logging.info('Logo inserted') + else: + logging.info('No logo defined') + else: + logging.info('Addlogo set to FALSE') + + + + else: + # 4 Pics + logo Layout + #----------------- Layout 1 big 3 small----- + + outer_border = 40 + inner_border = 10 + + smallPics_size = ( int( (self._pic_dims.outputSize[0] - ( outer_border * 2 ) - ( inner_border * 4 )) / 3 ) , + int( (self._pic_dims.outputSize[1] - ( outer_border * 2 ) - ( inner_border * 4 )) / 3 )) + largePics_size = ( ( smallPics_size[0] * 2 ), + ( smallPics_size[1] * 2 ) ) + logo_size = ( int( (self._pic_dims.outputSize[0] - ( inner_border * 2 ) - ( outer_border ) - largePics_size[0]) ), + int( (self._pic_dims.outputSize[0] - ( inner_border * 2 ) - ( outer_border ) - smallPics_size[1]) ) ) + + logging.info('Size logo "{}"'.format(logo_size)) + + if(self._addlogo): + if len(self._logo) > 0: + logging.info('Using logo "{}"'.format(self._logo)) + logo = Image.open(self._logo).convert("RGBA") + logo = logo.rotate(self._logo_rot, expand=True) + logo.thumbnail(logo_size, Image.ANTIALIAS) + offset = (((self._pic_dims.outputSize[0] - largePics_size[0] - outer_border - inner_border) // 2 ) - logo.size[0] // 2 , + ((largePics_size[1]//2) + outer_border )- logo.size[1] //2) + logging.info('Logo offset"{}"'.format(offset)) + picture.paste(logo,offset,logo) + logging.info('Logo inserted') + else: + logging.info('No logo defined') + else: + logging.info('Addlogo set to FALSE') + + # Image 0 + img = Image.open(self._pictures[0]) + img = img.convert('RGBA') + #img = img.rotate(45, expand=True) + img.thumbnail(largePics_size) + offset = ( self._pic_dims.outputSize[0] - img.size[0] - outer_border - inner_border , + outer_border ) + picture.paste(img, offset, img) + logging.info('Image0 inserted with size "{}"'.format(img.size)) + + # Image 1 + img = Image.open(self._pictures[1]) + img.thumbnail(smallPics_size) + offset = ( outer_border + inner_border, + self._pic_dims.outputSize[1] - outer_border - img.size[1] ) + picture.paste(img, offset) + logging.info('Image1 inserted') + + # Image 2 + img = Image.open(self._pictures[2]) + img.thumbnail(smallPics_size) + offset = ( self._pic_dims.outputSize[0] // 2- img.size[0] // 2, + self._pic_dims.outputSize[1] - outer_border - img.size[1] ) + picture.paste(img, offset) + logging.info('Image2 inserted') + + # Image 3 + img = Image.open(self._pictures[3]) + img.thumbnail(smallPics_size) + offset = ( self._pic_dims.outputSize[0] - outer_border - img.size[0] - inner_border , + self._pic_dims.outputSize[1] - outer_border - img.size[1] ) + picture.paste(img, offset) + logging.info('Image3 inserted') + + else: + for i in range(self._pic_dims.totalNumPictures): + logging.info('Pic "{}"'.format(i)) + shot = Image.open(self._pictures[i]) + resized = shot.resize(self._pic_dims.thumbnailSize) + picture.paste(resized, self._pic_dims.thumbnailOffset[self._pic_dims.thumbsLocation[i]]) + + if(self._addlogo): + + if len(self._logo) > 0: + logging.info('Using logo "{}"'.format(self._logo)) + logo = Image.open(self._logo).convert("RGBA") + logo = logo.rotate(self._logo_rot, expand=True) + if(self._pic_dims.totalNumPictures < (self._pic_dims.numPictures[0] * self._pic_dims.numPictures[1])): + logo_size = ((self._pic_dims.thumbnailSize[0] / 100)*90, + (self._pic_dims.thumbnailSize[1] / 100)*90) + logo.thumbnail(logo_size, Image.ANTIALIAS) + logopos = [i for i in range(self._pic_dims.numPictures[0] * self._pic_dims.numPictures[1]) if i not in self._pic_dims.thumbsLocation] # get postions without picture + offset = ((self._pic_dims.thumbnailOffset[logopos[0]])[0]+ (self._pic_dims.thumbnailSize[0] -logo.size[0]) // 2, # calculate offsets for 1 logo on the first available postion + (self._pic_dims.thumbnailOffset[logopos[0]])[1]+ (self._pic_dims.thumbnailSize[1] -logo.size[1]) // 2) + + else: + logo_size = ((self._pic_dims.thumbnailSize[0] / 100)*70, + (self._pic_dims.thumbnailSize[1] / 100)*70) + logo.thumbnail(logo_size, Image.ANTIALIAS) + offset = ((picture.size[0] - logo.size[0]) // 2, + (picture.size[1] - logo.size[1]) // 2) + + picture.paste(logo,offset,logo) + logging.info('Logo inserted') + else: + logging.info('No logo defined') + + + + byte_data = BytesIO() picture.save(byte_data, format='jpeg') self._comm.send(Workers.MASTER, diff --git a/photobooth/defaults.cfg b/photobooth/defaults.cfg index 5e87b307..aef7e4bc 100644 --- a/photobooth/defaults.cfg +++ b/photobooth/defaults.cfg @@ -3,10 +3,10 @@ module = PyQt5 # Start Photobooth in fullscreen mode (True/False) fullscreen = False -# Width of Photobooth (if not fullscreen) -width = 1024 -# Height of Photobooth (if not fullscreen) -height = 600 +# Width of Photobooth (if not fullscreen) orig: 1024 +width = 800 +# Height of Photobooth (if not fullscreen) orig: 600 +height = 480 # Hide cursor hide_cursor = False # Use specified style @@ -68,10 +68,10 @@ overwrite_error_message = num_x = 2 # Number of pictures in vertical direction num_y = 2 -# Size of output picture in horizontal direction -size_x = 3496 -# Size of output picture in vertical direction -size_y = 2362 +# Size of output picture in horizontal direction orig: 3496 +size_x = 2352 +# Size of output picture in vertical direction orig: 2362 +size_y = 1568 # Minimum distance between thumbnails in horizontal direction inner_dist_x = 20 # Minimum distance between thumbnails in vertical direction @@ -81,9 +81,21 @@ outer_dist_x = 40 # Minimum distance of thumbnails to border in vertical direction outer_dist_y = 40 # Leave out the specified pictures, e.g. for a logo (comma-separated list) -skip = +skip = 4 +# Add BG to Assembly (True/False) +addBg = True # Specify background image (filename, optional) background = +# Specify background Color (HTMLNotation without #) #ffffff = White +bgColor = ffffff +# Add Logo to Assembly (True/False) +addlogo = True +# Specify logo image (filename, optional) +logo = +#Specifiy logo rotation +logo_rot = 0 +#Specifiy if fancy Layout or not +fancy = False [Storage] # Basedir of output pictures diff --git a/photobooth/gui/Qt5Gui/Frames.py b/photobooth/gui/Qt5Gui/Frames.py index b49e9a12..24caadd3 100644 --- a/photobooth/gui/Qt5Gui/Frames.py +++ b/photobooth/gui/Qt5Gui/Frames.py @@ -685,9 +685,32 @@ def createPictureSettings(self): skip = QtWidgets.QLineEdit(self._cfg.get('Picture', 'skip')) self.add('Picture', 'skip', skip) + + fancy = QtWidgets.QCheckBox() + + fancy.setChecked(self._cfg.getBool('Picture', 'fancy')) + self.add('Picture', 'fancy', fancy) + + addlogo = QtWidgets.QCheckBox() + + addlogo.setChecked(self._cfg.getBool('Picture', 'addlogo')) + self.add('Picture', 'addlogo', addlogo) + + addBg = QtWidgets.QCheckBox() + + addBg.setChecked(self._cfg.getBool('Picture', 'addBg')) + self.add('Picture', 'addBg', addBg) + + lay_check = QtWidgets.QHBoxLayout() + lay_check.addWidget(skip) + lay_check.addWidget(QtWidgets.QLabel('fancy Layout:')) + lay_check.addWidget(fancy) bg = QtWidgets.QLineEdit(self._cfg.get('Picture', 'background')) self.add('Picture', 'background', bg) + + logo = QtWidgets.QLineEdit(self._cfg.get('Picture', 'logo')) + self.add('Picture', 'logo', logo) lay_num = QtWidgets.QHBoxLayout() lay_num.addWidget(num_x) @@ -709,26 +732,82 @@ def createPictureSettings(self): lay_outer_dist.addWidget(QtWidgets.QLabel('x')) lay_outer_dist.addWidget(outer_dist_y) - def file_dialog(): + def bg_file_dialog(): dialog = QtWidgets.QFileDialog.getOpenFileName - bg.setText(dialog(self, _('Select file'), os.path.expanduser('~'), + bg.setText(dialog(self, _('Select file'), os.path.expanduser('~/background'), 'Images (*.jpg *.png)')[0]) - file_button = QtWidgets.QPushButton(_('Select file')) - file_button.clicked.connect(file_dialog) - + bg_file_button = QtWidgets.QPushButton(_('Select file')) + bg_file_button.clicked.connect(bg_file_dialog) + lay_file = QtWidgets.QHBoxLayout() + lay_file.addWidget(addBg) lay_file.addWidget(bg) - lay_file.addWidget(file_button) + lay_file.addWidget(bg_file_button) + + def logo_file_dialog(): + dialog = QtWidgets.QFileDialog.getOpenFileName + logo.setText(dialog(self, _('Select file'), os.path.expanduser('~/logo'), + 'Images (*.jpg *.png)')[0]) + + logo_file_button = QtWidgets.QPushButton(_('Select file')) + logo_file_button.clicked.connect(logo_file_dialog) + + lay_logo = QtWidgets.QHBoxLayout() + lay_logo.addWidget(addlogo) + lay_logo.addWidget(logo) + lay_logo.addWidget(logo_file_button) + + logo_rot = QtWidgets.QSpinBox() + logo_rot.setRange(0, 360) + logo_rot.setValue(self._cfg.getInt('Picture', 'logo_rot')) + self.add('Picture', 'logo_rot', logo_rot) + + lay_logo_rot = QtWidgets.QHBoxLayout() + lay_logo_rot.addWidget(logo_rot) + + + + def show_colordiag(): + bgColor = '#' + self._cfg.get('Picture', 'bgColor') + curcol = QtGui.QColor(bgColor) + + colord = QtWidgets.QColorDialog() + colord.setCurrentColor(QtGui.QColor(curcol)) #not working dont know why + + color = colord.getColor() + if color.isValid(): + bgColor = color.name()[1:] + logging.info(bgColor) + else: + bgColor = 'ffffff' + + self.add('Picture', 'bgColor', bgColor) + curCol.setStyleSheet("QWidget { background-color: %s}" % color.name()) + + bgColor = self._cfg.get('Picture', 'bgColor') + self.add('Picture', 'bgColor', bgColor) + tempcol = '#' + bgColor + curCol = QtWidgets.QLabel('Hintergrund Farbe') + curCol.setStyleSheet("QWidget { background-color: %s}" % tempcol) + colorb = QtWidgets.QPushButton('Open color dialog') + colorb.clicked.connect(show_colordiag) + + lay_col = QtWidgets.QHBoxLayout() + lay_col.addWidget(curCol) + lay_col.addWidget(colorb) layout = QtWidgets.QFormLayout() layout.addRow(_('Number of shots per picture:'), lay_num) layout.addRow(_('Size of assembled picture [px]:'), lay_size) layout.addRow(_('Min. distance between shots [px]:'), lay_inner_dist) layout.addRow(_('Min. distance border to shots [px]:'), lay_outer_dist) - layout.addRow(_('Skip pictures:'), skip) + layout.addRow(_('Skip pictures:'), lay_check) #websta :orgig: skip layout.addRow(_('Background image:'), lay_file) - + layout.addRow(_('Add Logo image:'), lay_logo) + layout.addRow(_('Logo rotation:'), lay_logo_rot) + layout.addRow(_('Background color:'), lay_col) + widget = QtWidgets.QWidget() widget.setLayout(layout) return widget @@ -1015,6 +1094,18 @@ def storeConfigAndRestart(self): self._cfg.set('Picture', 'skip', self.get('Picture', 'skip').text()) self._cfg.set('Picture', 'background', self.get('Picture', 'background').text()) + self._cfg.set('Picture', 'logo', + self.get('Picture', 'logo').text()) + self._cfg.set('Picture', 'logo_rot', + self.get('Picture', 'logo_rot').text()) + self._cfg.set('Picture', 'fancy', + str(self.get('Picture', 'fancy').isChecked())) + self._cfg.set('Picture', 'addlogo', + str(self.get('Picture', 'addlogo').isChecked())) + self._cfg.set('Picture', 'addBg', + str(self.get('Picture', 'addBg').isChecked())) + self._cfg.set('Picture', 'bgColor', + self.get('Picture', 'bgColor')) self._cfg.set('Storage', 'basedir', self.get('Storage', 'basedir').text()) diff --git a/photobooth/gui/Qt5Gui/__init__.py b/photobooth/gui/Qt5Gui/__init__.py index a6c0d977..0f49b105 100644 --- a/photobooth/gui/Qt5Gui/__init__.py +++ b/photobooth/gui/Qt5Gui/__init__.py @@ -21,6 +21,7 @@ styles = (('default', 'stylesheets/default.qss'), ('dark (1024 x 600 px)', 'stylesheets/dark-1024x600.qss'), ('dark (800 x 600 px)', 'stylesheets/dark-800x600.qss'), + ('mydark (800 x 600 px)', 'stylesheets/dark_small.qss'), ('pastel (1024 x 600 px)', 'stylesheets/pastel-1024x600.qss'), ('pastel (800 x 600 px)', 'stylesheets/pastel-800x600.qss')) diff --git a/photobooth/gui/Qt5Gui/stylesheets/dark-800x600.qss b/photobooth/gui/Qt5Gui/stylesheets/dark-800x600.qss index 61b237c4..35097d6c 100644 --- a/photobooth/gui/Qt5Gui/stylesheets/dark-800x600.qss +++ b/photobooth/gui/Qt5Gui/stylesheets/dark-800x600.qss @@ -201,12 +201,12 @@ QGroupBox { QTabWidget QWidget { color: #333333; - font-size: 30px; + font-size: 20px; } QCheckBox::indicator { - width: 30px; - height: 30px; + width: 20px; + height: 20px; background-color: transparent; border-style: outset; border-width: 2px; @@ -215,7 +215,7 @@ QCheckBox::indicator { } QCheckBox::indicator::checked { - background-image: url(photobooth/gui/Qt5Gui/images/checkmark.png); + image: url(photobooth/gui/Qt5Gui/images/checkmark.png); background-repeat: no-repeat; } diff --git a/photobooth/gui/Qt5Gui/stylesheets/dark_small.qss b/photobooth/gui/Qt5Gui/stylesheets/dark_small.qss new file mode 100644 index 00000000..78f97434 --- /dev/null +++ b/photobooth/gui/Qt5Gui/stylesheets/dark_small.qss @@ -0,0 +1,239 @@ +/* Outer items */ + +QWidget { + background-color: transparent; + color: #eeeeee; + font-family: AmaticSC, sans-serif; + font-size: 25px; +} + +QMainWindow { + background: #000000; + color: #eeeeee; +} + +/* General controls */ + +QPushButton { + background-color: transparent; + border-style: outset; + border-width: 1px; + border-radius: 15px; + border-color: #eeeeee; + font-size: 25px; + padding: 10px; +} + +QPushButton:pressed { + background-color: #66eeeeee; +} + +/* Idle Screen */ + +QFrame#IdleMessage { + background-image: url(photobooth/gui/Qt5Gui/images/arrow.png); + background-repeat: no-repeat; + padding: 80px 400px 120px 80px; +} + +QFrame#IdleMessage QLabel { + font-size: 80px; + qproperty-alignment: AlignCenter; +} + +QFrame#IdleMessage QPushButton { + border: none; + color: rgba(255, 27, 0, 200); + font-size: 100px; + text-align: center; +} + +QFrame#IdleMessage QPushButton:pressed { + background-color: rgba(255, 27, 0, 200); + color: #eeeeee; +} + +/* Greeter Screen */ + +QFrame#GreeterMessage { + padding: 30px; +} + +QFrame#GreeterMessage QLabel#title { + font-size: 90px; + margin: 0; + padding: 0; + qproperty-alignment: AlignCenter; +} + +QFrame#GreeterMessage QPushButton#button { + border: none; + font-size: 25px; + margin: 0; + min-height: 40px; + padding: 0; + text-align: center; +} + +QFrame#GreeterMessage QLabel#message { + font-size: 60px; + margin: 0; + padding: 0; + qproperty-alignment: AlignCenter; +} + +/* Countdown Screen */ + +QFrame#CountdownMessage { + background-color: #eeeeee; + border-style: outset; + border-width: 2px; + border-radius: 30px; + border-color: #eeeeee; + margin: 20px; + padding: 30px; +} + +/* Pose Screen */ + +QFrame#PoseMessage { + background-image: url(photobooth/gui/Qt5Gui/images/camera.png); + background-repeat: no-repeat; + padding: 380px 80px 80px 80px; +} + +QFrame#PoseMessage QLabel { + font-size: 60px; + qproperty-alignment: AlignCenter; +} + +/* Wait Screen */ + +QFrame#WaitMessage { + padding: 350px 80px 80px 80px; +} + +QFrame#WaitMessage QLabel { + font-size: 40px; + qproperty-alignment: AlignCenter; +} + +/* Picture Screen */ + +QFrame#PictureMessage { + margin: 30px; +} + +/* Overlay message */ + +QWidget#TransparentOverlay { + background-color: #aaeeeeee; + border-style: outset; + border-width: 2px; + border-radius: 30px; + border-color: #eeeeee; + color: #333333; + padding: 40px; +} + +/* Postprocess message */ + +QWidget#PostprocessMessage QLabel { + color: #333333; + font-size: 60px; + qproperty-alignment: AlignCenter; +} + +QWidget#PostprocessMessage QPushButton { + color: #333333; + border-color: #333333; + margin: 20px; +} + +QWidget#PostprocessMessage QPushButton:pressed { + background-color: #66eeeeee; +} + +QWidget#PostprocessMessage QPushButton:disabled { + background-color: #66eeeeee; + color: #33eeeeee; + border-color: #33eeeeee; +} + +/* Customizing settings */ + +QTabWidget::pane { + background-color: #eeeeee; + border-style: outset; + border-width: 1px; + border-radius: 15px; + border-color: #eeeeee; + color: #eeeeee; + padding: 10px; +} + +QTabWidget::tab-bar { + alignment: center; +} + +QTabBar::tab { + background-color: transparent; + border-style: outset; + border-width: 2px; + border-top-left-radius: 15px; + border-top-right-radius: 15px; + border-color: #eeeeee; + color: #eeeeee; + padding: 8px; +} + +QTabBar::tab:selected { + background-color: #33ffffff; +} + +QGroupBox { + background-color: transparent; + border-style: outset; + border-width: 1px; + border-radius: 15px; + border-color: #eeeeee; + margin: 0px; + padding: 4px; +} + +QTabWidget QWidget { + color: #333333; + font-size: 15px; +} + +QCheckBox::indicator { + width: 15px; + height: 15px; + background-color: transparent; + border-style: outset; + border-width: 2px; + border-radius: 5px; + border-color: #333333; +} + +QCheckBox::indicator::checked { + image: url(photobooth/gui/Qt5Gui/images/checkmark.png); + background-repeat: no-repeat; +} + +QComboBox, QDateEdit, QLineEdit, QSpinBox, QTimeEdit { + background-color: #eeeeee; + color: #333333; +} + +QComboBox QAbstractItemView { + background-color: #cccccc; + color: #333333; + selection-background-color: #eeeeee; + selection-color: #333333; +} + +QComboBox QAbstractItemView::item { + margin: 5px; + min-height: 50px; +} diff --git a/photobooth/worker/__init__.py b/photobooth/worker/__init__.py index 81e03bbb..b65aeeeb 100644 --- a/photobooth/worker/__init__.py +++ b/photobooth/worker/__init__.py @@ -43,8 +43,8 @@ def __init__(self, config, comm): self._pic_list = PictureList(basename) # Picture list for individual shots - path = os.path.join(config.get('Storage', 'basedir'), - config.get('Storage', 'basename') + '_shot_') + path = os.path.join(config.get('Storage', 'basedir'),'src') + path = os.path.join(path,config.get('Storage', 'basename') + '_shot_') basename = strftime(path, localtime()) self._shot_list = PictureList(basename) @@ -71,6 +71,7 @@ def initPictureTasks(self, config): self._picture_tasks = [] # PictureSaver for single shots + self._picture_tasks.append(PictureSaver(self._shot_list.basename)) def run(self): From 97507464508e6088db38fdb340b9ed5214023993 Mon Sep 17 00:00:00 2001 From: websta911 <52451724+websta911@users.noreply.github.com> Date: Thu, 19 Sep 2019 12:22:00 +0200 Subject: [PATCH 2/4] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa433eeb..3786f247 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# photobooth +# photobooth slightly adapted from reuterbal Go Buy him a coffee [![Buy me a coffee](https://www.buymeacoffee.com/assets/img/custom_images/black_img.png)](https://www.buymeacoffee.com/reuterbal) From 871b5261f9ea729f7c3c65aedc4b9a1b98bca594 Mon Sep 17 00:00:00 2001 From: websta911 <52451724+websta911@users.noreply.github.com> Date: Tue, 24 Sep 2019 13:41:50 +0200 Subject: [PATCH 3/4] Update INSTALL.md --- INSTALL.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/INSTALL.md b/INSTALL.md index dcd4be0a..5f85acb3 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -149,3 +149,9 @@ You can trigger the countdown via space bar or an external button. To exit the application, use the Esc-key or an external button. You can directly startup the photobooth to the idle screen (skipping the welcome screen) by appending the parameter `--run`. + +AUTOSTART: +vim ~/.config/lxsession/LXDE-pi/autostart +@lxterminal -e /home/pi/PB/autostart.sh + +in autostart.sh you can enter "sleep 2" for some delay while starting. From cc3aceaaf55f7ffdcfabe935e5aa96370f98381f Mon Sep 17 00:00:00 2001 From: websta911 <52451724+websta911@users.noreply.github.com> Date: Thu, 7 Nov 2019 21:35:34 +0100 Subject: [PATCH 4/4] Update PictureDimensions.py added if clause for enabling single pictures --- photobooth/camera/PictureDimensions.py | 28 +++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/photobooth/camera/PictureDimensions.py b/photobooth/camera/PictureDimensions.py index a6f0e4a4..faa928e7 100644 --- a/photobooth/camera/PictureDimensions.py +++ b/photobooth/camera/PictureDimensions.py @@ -78,19 +78,23 @@ def computeThumbnailDimensions(self): self._thumb_offsets = [] #websta changedfrom thumbs - for i in range(self.numPictures[0] * self.numPictures[1]): - pos = (i % self.numPictures[0], i // self.numPictures[0]) - #self._thumb_offsets.append(tuple(border[j] + (pos[j] + 1) * thumb_dist[j] + pos[j] * self.thumbnailSize[j] for j in range(2))) - # websta: changed to calculate from center of image so the spacing is horizontally and vertically equal - thumb_offs = [] - for j in range(2): - if pos[j] < 1 : - thumb_offs.append(self.outputSize[j]//2 - self.thumbnailSize[j] - (thumb_dist[1] // 2)) - else : - thumb_offs.append(self.outputSize[j]//2 + (thumb_dist[1] // 2)) - - self._thumb_offsets.append(tuple(thumb_offs[j] + if (self.numPictures[0] * self.numPictures[1]) > 1: #for mor than one picture + for i in range(self.numPictures[0] * self.numPictures[1]): + pos = (i % self.numPictures[0], i // self.numPictures[0]) + #self._thumb_offsets.append(tuple(border[j] + (pos[j] + 1) * thumb_dist[j] + pos[j] * self.thumbnailSize[j] for j in range(2))) + # websta: changed to calculate from center of image so the spacing is horizontally and vertically equal + thumb_offs = [] + for j in range(2): + if pos[j] < 1 : + thumb_offs.append(self.outputSize[j]//2 - self.thumbnailSize[j] - (thumb_dist[1] // 2)) + else : + thumb_offs.append(self.outputSize[j]//2 + (thumb_dist[1] // 2)) + + self._thumb_offsets.append(tuple(thumb_offs[j] for j in range(2))) + else: # if just one picture center the picture + self._thumb_offsets.append(tuple((self.outputSize[j]//2 - self.thumbnailSize[j]//2) + for j in range(2))) logging.debug(('Assembled picture will contain {} ({}x{}) pictures ' 'in positions {}').format(self.totalNumPictures,