Beispiel #1
0
    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)
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #5
0
    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)
Beispiel #6
0
    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))
Beispiel #7
0
    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
Beispiel #8
0
    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'))
Beispiel #9
0
 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()
Beispiel #10
0
 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()
Beispiel #11
0
    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)
Beispiel #12
0
    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()
Beispiel #13
0
 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()
Beispiel #14
0
 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()
Beispiel #15
0
    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
Beispiel #16
0
    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()
Beispiel #17
0
 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
Beispiel #18
0
    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)
Beispiel #19
0
    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)
Beispiel #20
0
 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()
Beispiel #21
0
    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()
Beispiel #22
0
    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
Beispiel #23
0
 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
Beispiel #24
0
    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
Beispiel #25
0
    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
Beispiel #26
0
    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)
Beispiel #27
0
    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)
Beispiel #28
0
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)))
Beispiel #29
0
    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
Beispiel #30
0
    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