def state_processing_do(self, cfg, app): idx = app.capture_choices.index(app.capture_nbr) with timeit("Creating the final picture"): captures = app.camera.get_captures() factory = get_picture_factory(captures, cfg.get('PICTURE', 'orientation')) self._pm.hook.pibooth_setup_picture_factory(cfg=cfg, opt_index=idx, factory=factory) app.previous_picture = factory.build() savedir = cfg.getpath('GENERAL', 'directory') app.previous_picture_file = osp.join( savedir, osp.basename(app.dirname) + "_pibooth.jpg") factory.save(app.previous_picture_file) if cfg.getboolean('WINDOW', 'animate') and app.capture_nbr > 1: with timeit("Asyncronously generate pictures for animation"): for capture in captures: factory = get_picture_factory( (capture, ), cfg.get('PICTURE', 'orientation'), force_pil=True) self._pm.hook.pibooth_setup_picture_factory( cfg=cfg, opt_index=idx, factory=factory) self.factory_pool.add(factory)
def entry_actions(self): self.app.window.show_work_in_progress() with timeit("Creating merged picture"): footer_texts = [ self.app.config.get('PICTURE', 'footer_text1'), self.app.config.get('PICTURE', 'footer_text2') ] bg_color = self.app.config.gettyped('PICTURE', 'bg_color') if not isinstance(bg_color, (tuple, list)): # Path to a background image bg_color = Image.open( self.app.config.getpath('PICTURE', 'bg_color')) text_color = self.app.config.gettyped('PICTURE', 'text_color') orientation = self.app.config.get('PICTURE', 'orientation') self.app.previous_picture = concatenate_pictures( self.app.camera.get_captures(), footer_texts, bg_color, text_color, orientation) self.app.previous_picture_file = osp.join( self.app.savedir, osp.basename(self.app.dirname) + "_pibooth.jpg") with timeit("Save the merged picture in {}".format( self.app.previous_picture_file)): self.app.previous_picture.save(self.app.previous_picture_file)
def build(self, rebuild=False): """Build the final image or doas nothing if the final image has already been built previously. :param rebuild: force re-build image :type rebuild: bool :return: PIL.Image instance :rtype: object """ if not self._final or rebuild: with timeit("Use {} to create background".format(self.name)): image = self._build_background() with timeit("Use {} to concatenate images".format(self.name)): image = self._build_matrix(image) with timeit("Use {} to assemble final image".format(self.name)): self._final = self._build_final_image(image) with timeit("Use {} to draw texts".format(self.name)): self._build_texts(self._final) if self._outline: with timeit("Use {} to outline boundary borders".format( self.name)): self._build_outlines(self._final) return self._final
def state_processing_do(self, cfg, app): idx = app.capture_choices.index(app.capture_nbr) with timeit("Saving raw captures"): captures = app.camera.get_captures() for savedir in cfg.gettuple('GENERAL', 'directory', 'path'): rawdir = osp.join(savedir, "raw", app.capture_date) os.makedirs(rawdir) for capture in captures: count = captures.index(capture) img_path = osp.join(rawdir, "pibooth{:03}.jpg".format(count)) capture.save(img_path) # Color Filtering... for capture in captures: count = captures.index(capture) filter_count = 1 for filterName in cfg.gettyped('FILTERS', 'filters_list'): print("Filter " + filterName) filter_controller.doFilter( filterName, capture, osp.join( rawdir, "pibooth{:03}-f{}.jpg".format( count, filter_count))) filter_count = filter_count + 1 if filter_count > 3: break # 3 filters max allowed break # Only preview on the first picture for performance with timeit("Creating the final picture"): default_factory = get_picture_factory( captures, cfg.get('PICTURE', 'orientation')) factory = self._pm.hook.pibooth_setup_picture_factory( cfg=cfg, opt_index=idx, factory=default_factory) app.previous_picture = Image.open( '/home/pi/pibooth/assets/test.gif') #factory.build() for savedir in cfg.gettuple('GENERAL', 'directory', 'path'): app.previous_picture_file = osp.join(savedir, app.picture_filename) factory.save(app.previous_picture_file) if cfg.getboolean('WINDOW', 'animate') and app.capture_nbr > 1: with timeit("Asyncronously generate pictures for animation"): for capture in captures: default_factory = get_picture_factory( (capture, ), cfg.get('PICTURE', 'orientation'), force_pil=True, dpi=200) factory = self._pm.hook.pibooth_setup_picture_factory( cfg=cfg, opt_index=idx, factory=default_factory) factory.set_margin(factory._margin // 3) # 1/3 since DPI is divided by 3 self.factory_pool.add(factory)
def do_actions(self, events): self.app.window.set_picture_number(self.count + 1, self.app.nbr_captures) pygame.event.pump() if self.app.config.getboolean('WINDOW', 'preview_countdown'): self.app.camera.preview_countdown(self.app.config.getint('WINDOW', 'preview_delay')) else: self.app.camera.preview_wait(self.app.config.getint('WINDOW', 'preview_delay')) capture_path = osp.join(self.app.dirname, "pibooth{:03}.jpg".format(self.count)) if self.app.config.getboolean('WINDOW', 'preview_stop_on_capture'): self.app.camera.stop_preview() with timeit("Take picture and save it in {}".format(capture_path)): if self.app.config.getboolean('WINDOW', 'flash'): with self.app.window.flash(2): self.app.camera.capture(capture_path) else: self.app.camera.capture(capture_path) self.count += 1 if self.app.config.getboolean('WINDOW', 'preview_stop_on_capture') and self.count < self.app.nbr_captures: # Restart preview only if other captures needed self.app.camera.preview(self.app.window)
def do_actions(self, events): if self.app.find_print_event( events ) and self.app.previous_picture_file and self.app.printer.is_installed( ): if self.app.nbr_printed >= self.app.config.getint( 'PRINTER', 'max_duplicates'): LOGGER.warning( "Too many duplicates sent to the printer (%s max)", self.app.config.getint('PRINTER', 'max_duplicates')) return with timeit("Send final picture to printer"): self.app.led_print.switch_on() self.app.printer.print_file( self.app.previous_picture_file, self.app.config.getint('PRINTER', 'nbr_copies')) time.sleep(1) # Just to let the LED switched on self.app.nbr_printed += 1 if self.app.nbr_printed >= self.app.config.getint( 'PRINTER', 'max_duplicates'): self.app.window.show_intro(self.app.previous_picture, False) self.app.led_print.switch_off() else: self.app.led_print.blink() event = self.app.find_print_status_event(events) if event: self.app.window.set_print_number(len(event.tasks))
def do_actions(self, events): if self.app.find_print_qr_event(events): # print qr code: if self.app.qr_printer.nbr_printed == 0: LOGGER.info("print qr code now") self.app.qr_printer.print_file( self.app.previous_picture_qr_file_print, 1) elif self.app.find_print_event( events) and self.app.previous_print_picture_file: with timeit("Send final picture to printer"): self.app.led_print.switch_on() print_value = self.app.config.get('SERVER', 'print_qr_code') if print_value == "Picture" or print_value == "Picture and Qr Code": self.app.printer.print_file( self.app.previous_print_picture_file, self.app.config.getint('PRINTER', 'pictures_per_page')) if print_value == "Qr Code" or print_value == "Picture and Qr Code": self.app.printer.print_file( self.app.previous_picture_qr_file, self.app.config.getint('PRINTER', 'pictures_per_page')) time.sleep(1) # Just to let the LED switched on self.app.nbr_duplicates += 1 self.app.led_print.blink() self.printed = True
def _get_preview_capture(self): """Capture a new preview image. """ with timeit('Capturing new preview image'): camera_file = self._cam.capture_preview() file_data = gp.check_result( gp.gp_file_get_data_and_size(camera_file)) image = Image.open(io.BytesIO(memoryview(file_data))) if self._preview_hflip: image = image.transpose(Image.FLIP_LEFT_RIGHT) if self._rotation: image = image.rotate(self._rotation) image = image.resize( sizing.new_size_keep_aspect_ratio(image.size, self.resolution, 'outer')) image = image.crop( sizing.new_size_by_croping(image.size, self.resolution)) # Resize to the window rect (outer because rect already resized innner, see 'get_rect') rect = self.get_rect() return image.resize( sizing.new_size_keep_aspect_ratio(image.size, (rect.width, rect.height), 'outer'))
def entry_actions(self): with timeit("Show picture choice (no default set)"): self.app.window.show_choice() self.app.max_captures = None self.app.led_picture.blink() self.app.led_print.blink() self.timer.start()
def entry_actions(self): with timeit("Show picture choice (nothing selected)"): self.app.window.show_choice(self.app.capture_choices) self.app.nbr_captures = None self.app.led_picture.blink() self.app.led_print.blink() self.timer.start()
def do_actions(self, events): with timeit("Creating the final picture"): captures = self.app.camera.get_captures() backgrounds = self.app.config.gettuple('PICTURE', 'backgrounds', ('color', 'path'), 2) if self.app.capture_nbr == self.app.capture_choices[0]: background = backgrounds[0] else: background = backgrounds[1] overlays = self.app.config.gettuple('PICTURE', 'overlays', 'path', 2) if self.app.capture_nbr == self.app.capture_choices[0]: overlay = overlays[0] else: overlay = overlays[1] texts = [self.app.config.get('PICTURE', 'footer_text1').strip('"'), self.app.config.get('PICTURE', 'footer_text2').strip('"')] colors = self.app.config.gettuple('PICTURE', 'text_colors', 'color', len(texts)) text_fonts = self.app.config.gettuple('PICTURE', 'text_fonts', str, len(texts)) alignments = self.app.config.gettuple('PICTURE', 'text_alignments', str, len(texts)) def _setup_maker(m): m.set_background(background) if any(elem != '' for elem in texts): for params in zip(texts, text_fonts, colors, alignments): m.add_text(*params) if self.app.config.getboolean('PICTURE', 'captures_cropping'): m.set_cropping() if overlay: m.set_overlay(overlay) if self.app.config.getboolean('GENERAL', 'debug'): m.set_outlines() maker = get_picture_maker(captures, self.app.config.get('PICTURE', 'orientation')) _setup_maker(maker) self.app.previous_picture = maker.build() self.app.previous_picture_file = osp.join(self.app.savedir, osp.basename(self.app.dirname) + "_pibooth.jpg") maker.save(self.app.previous_picture_file) if self.app.config.getboolean('WINDOW', 'animate') and self.app.capture_nbr > 1: with timeit("Asyncronously generate pictures for animation"): for capture in captures: maker = get_picture_maker((capture,), self.app.config.get('PICTURE', 'orientation'), force_pil=True) _setup_maker(maker) self.app.makers_pool.add(maker)
def state_print_enter(self, cfg, app, win): with timeit("Display the final picture"): win.set_print_number(len(app.printer.get_all_tasks()), not app.printer.is_available()) win.show_print(app.previous_picture) # Reset timeout in case of settings changed self.print_view_timer.timeout = cfg.getfloat('PRINTER', 'printer_delay') self.print_view_timer.start()
def entry_actions(self): with timeit("Show picture choice (nothing selected)"): self.app.window.set_print_number(0) # Hide printer status self.app.window.show_choice(self.app.capture_choices) self.app.capture_nbr = None self.app.led_capture.blink() self.app.led_print.blink() self.timer.start()
def entry_actions(self): self.printed = False with timeit("Display the merged picture"): self.app.window.set_print_number( len(self.app.printer.get_all_tasks())) self.app.window.show_print(self.app.previous_picture) self.app.led_print.blink() self.timer.start()
def state_print_do(self, cfg, app, events): if app.find_print_event(events) and app.previous_picture_file: with timeit("Send final picture to printer"): app.printer.print_file( app.previous_picture_file, cfg.getint('PRINTER', 'pictures_per_page')) app.nbr_duplicates += 1
def entry_actions(self): self.printed = False if self.timer.timeout == 0: return # Don't show print state with timeit("Display the merged picture"): self.app.window.show_print(self.app.previous_picture) self.app.led_print.blink() self.timer.start()
def get_captures(self): """Return all buffered captures as PIL images (buffer dropped after call). """ images = [] for path in sorted(self._captures): with timeit("loading an image ({})".format(path)): images.append(self._post_process_capture(path)) self.drop_captures() return images
def do_actions(self, events): if self.app.config.getboolean( 'WINDOW', 'animate' ) and self.app.previous_animated and self.timer.is_timeout(): previous_picture = next(self.app.previous_animated) self.app.window.show_intro( previous_picture, self.app.printer.is_installed() and self.app.nbr_duplicates < self.app.config.getint( 'PRINTER', 'max_duplicates') and not self.app.printer_unavailable) self.timer.start() else: previous_picture = self.app.previous_picture if self.app.find_print_event(events) and self.app.previous_picture_file and self.app.printer.is_installed()\ and not (self.final_display_timer and self.final_display_timer.is_timeout()): if self.app.nbr_duplicates >= self.app.config.getint( 'PRINTER', 'max_duplicates'): LOGGER.warning( "Too many duplicates sent to the printer (%s max)", self.app.config.getint('PRINTER', 'max_duplicates')) return elif self.app.printer_unavailable: LOGGER.warning( "Maximum number of printed pages reached (%s/%s max)", self.app.printer.nbr_printed, self.app.config.getint('PRINTER', 'max_pages')) return with timeit("Send final picture to printer"): self.app.led_print.switch_on() self.app.printer.print_file( self.app.previous_picture_file, self.app.config.getint('PRINTER', 'pictures_per_page')) time.sleep(1) # Just to let the LED switched on self.app.nbr_duplicates += 1 if self.app.nbr_duplicates >= self.app.config.getint( 'PRINTER', 'max_duplicates') or self.app.printer_unavailable: self.app.window.show_intro(previous_picture, False) self.app.led_print.switch_off() else: self.app.led_print.blink() event = self.app.find_print_status_event(events) if event: self.app.window.set_print_number(len(event.tasks), self.app.printer_unavailable) if self.final_display_timer and self.final_display_timer.is_timeout(): self.app.window.show_intro(None, False)
def entry_actions(self): self.app.window.show_work_in_progress() with timeit("Creating merged picture"): footer_texts = [ self.app.config.get('PICTURE', 'footer_text1'), self.app.config.get('PICTURE', 'footer_text2') ] bg_color = self.app.config.gettyped('PICTURE', 'bg_color') text_color = self.app.config.gettyped('PICTURE', 'text_color') self.app.previous_picture = generate_picture_from_files( self.app.captures, footer_texts, bg_color, text_color) self.app.previous_picture_file = osp.join( self.app.dirname, time.strftime("%Y-%m-%d-%H-%M-%S") + "_ptb.jpg") with timeit("Save the merged picture in {}".format( self.app.previous_picture_file)): self.app.previous_picture.save(self.app.previous_picture_file)
def do_actions(self, events): if self.app.find_print_event( events ) and self.app.previous_picture_file and self.app.printer.is_installed( ): with timeit("Send final picture to printer"): self.app.led_print.switch_on() self.app.printer.print_file(self.app.previous_picture_file) time.sleep(1) self.app.led_print.blink()
def entry_actions(self): self.printed = False with timeit("Display the final picture"): self.app.window.set_print_number(len(self.app.printer.get_all_tasks()), self.app.printer_unavailable) self.app.window.show_print(self.app.previous_picture) self.app.led_print.blink() # Reset timeout in case of settings changed self.timer.timeout = self.app.config.getfloat('PRINTER', 'printer_delay') self.timer.start()
def do_actions(self, events): if self.app.find_print_event(events) and self.app.previous_picture_file: with timeit("Send final picture to printer"): self.app.led_print.switch_on() self.app.printer.print_file(self.app.previous_picture_file) time.sleep(2) # Just to let the LED switched on self.app.nbr_printed += 1 self.app.led_print.blink() self.printed = True
def state_print_do(self, cfg, app, events): if app.find_capture_event(events): with timeit("Putting the capture in the forget folder"): file_dir, file_name = osp.split(app.previous_picture_file) forget_dir = osp.join(file_dir, "forget") if not os.path.exists(forget_dir): os.makedirs(forget_dir) os.rename(app.previous_picture_file, osp.join(forget_dir, file_name)) self._reset_vars(app) app.previous_picture = self.second_previous_picture app.nbr_duplicates = cfg.getint('PRINTER', 'max_duplicates') + 1
def do_actions(self, events): if self.timer.timeout == 0: return # Don't show print state if self.app.find_print_event( events) and self.app.previous_picture_file: with timeit("Send final picture to printer"): self.app.led_print.switch_on() self.app.printer.print_file(self.app.previous_picture_file) time.sleep(1) self.app.led_print.blink() self.printed = True
def do_actions(self, events): if self.app.find_print_event(events) and self.app.previous_picture_file: with timeit("Send final picture to printer"): self.app.led_print.switch_on() self.app.printer.print_file(self.app.previous_picture_file, self.app.config.getint('PRINTER', 'pictures_per_page')) time.sleep(1) # Just to let the LED switched on self.app.nbr_duplicates += 1 self.app.led_print.blink() self.printed = True
def state_processing_do(self, cfg, app): idx = app.capture_choices.index(app.capture_nbr) with timeit("Saving raw captures"): captures = app.camera.get_captures() for savedir in cfg.gettuple('GENERAL', 'directory', 'path'): rawdir = osp.join(savedir, "raw", app.capture_date) os.makedirs(rawdir) for capture in captures: count = captures.index(capture) capture.save( osp.join(rawdir, "pibooth{:03}.jpg".format(count))) with timeit("Creating the final picture"): default_factory = get_picture_factory( captures, cfg.get('PICTURE', 'orientation')) factory = self._pm.hook.pibooth_setup_picture_factory( cfg=cfg, opt_index=idx, factory=default_factory) app.previous_picture = factory.build() for savedir in cfg.gettuple('GENERAL', 'directory', 'path'): app.previous_picture_file = osp.join(savedir, app.picture_filename) factory.save(app.previous_picture_file) if cfg.getboolean('WINDOW', 'animate') and app.capture_nbr > 1: with timeit("Asyncronously generate pictures for animation"): for capture in captures: default_factory = get_picture_factory( (capture, ), cfg.get('PICTURE', 'orientation'), force_pil=True, dpi=200) factory = self._pm.hook.pibooth_setup_picture_factory( cfg=cfg, opt_index=idx, factory=default_factory) factory.set_margin(factory._margin // 3) # 1/3 since DPI is divided by 3 self.factory_pool.add(factory)
def entry_actions(self): self.app.window.show_work_in_progress() with timeit("Creating merged picture"): footer_texts = [self.app.config.get('PICTURE', 'footer_text1'), self.app.config.get('PICTURE', 'footer_text2')] bg_color = self.app.config.gettyped('PICTURE', 'bg_color') if not isinstance(bg_color, (tuple, list)): # Path to a background image bg_color = Image.open(self.app.config.getpath('PICTURE', 'bg_color')) text_color = self.app.config.gettyped('PICTURE', 'text_color') orientation = self.app.config.get('PICTURE', 'orientation') self.app.previous_picture = concatenate_pictures( self.app.camera.get_captures(), footer_texts, bg_color, text_color, orientation) self.app.previous_picture_file = osp.join(self.app.dirname, time.strftime("%y%m%d%H%M") + ".jpg") #self.app.previous_picture_file = osp.join(self.app.dirname, time.strftime("%Y-%m-%d-%H-%M") + ".jpg") # pr #LOGGER.debug("generate qrcode") #cmd = "qr " + self.app.previous_picture_file + " > ~/qrcode.png" #os.system(cmd) with timeit("Save the merged picture in {}".format(self.app.previous_picture_file)): self.app.previous_picture.save(self.app.previous_picture_file)
def state_processing_do(cfg, app): with timeit("Saving filtered raw captures"): captures = app.camera.get_captures() for savedir in cfg.gettuple('GENERAL', 'directory', 'path'): rawdir = osp.join(savedir, "raw", app.capture_date) print(">> " + rawdir) for capture in captures: count = captures.index(capture) print(count) # img_path = osp.join(rawdir, "pibooth{:03}.jpg".format(count)) filter_controller.pilgram_aden( capture, osp.join(rawdir, "pibooth{:03}-aden.jpg".format(count)))
def save(self, path): """Build if not already done and save final image in a file. :param path: path to save :type path: str :return: PIL.Image instance :rtype: object """ dirname = osp.dirname(osp.abspath(path)) if not osp.isdir(dirname): os.mkdir(dirname) image = self.build() with timeit("Save image '{}'".format(path)): image.save(path) return image
def state_print_do(self, cfg, app, events): if app.find_capture_event(events): with timeit("Putting the capture in the forget folder"): file_dir, file_name = osp.split(app.previous_picture_file) forget_dir = osp.join(file_dir, "forget") if not os.path.exists(forget_dir): os.makedirs(forget_dir) os.rename(app.previous_picture_file, osp.join(forget_dir, file_name)) self._reset_vars(app) app.previous_picture = self.second_previous_picture # Deactivate the print function for the backuped picture # as we don't known how many times it has already been printed app.nbr_duplicates = cfg.getint('PRINTER', 'max_duplicates') + 1