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. diff --git a/PBlogo.png b/PBlogo.png new file mode 100644 index 00000000..b012d630 Binary files /dev/null and b/PBlogo.png differ 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) 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..faa928e7 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,33 @@ 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: - 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] + #websta changedfrom thumbs + 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, self.numPictures[0], - self.numPictures[1], thumbs)) + self.numPictures[1], self._thumbs)) def computePreviewDimensions(self, config): @@ -103,6 +117,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):