def __init__(self, piece_theme: str, size: int = 70):

        piece_dir = os.path.join('data', 'piece', piece_theme)

        #: Maps pieces to their corresponding .svg filenames
        self.pieces_map = {
            'r': 'bR',
            'q': 'bQ',
            'n': 'bN',
            'k': 'bK',
            'p': 'bP',
            'b': 'bB',
            'R': 'wR',
            'Q': 'wQ',
            'N': 'wN',
            'K': 'wK',
            'P': 'wP',
            'B': 'wB'
        }

        # Reads the available piece theme's .svg images and save them as .png of appropraite size
        for piece in self.pieces_map:
            piece_path = os.path.join(piece_dir,
                                      self.pieces_map[piece] + '.svg')
            image = VipsImage.thumbnail(piece_path, size, height=size)
            image.write_to_file(f"Images/{ self.pieces_map[piece]}.png")

        #: Dictionary where pieces are the keys and corresponding PIL Images are the values
        self.piece_imgs = dict()
        for piece in self.pieces_map:
            self.piece_imgs[piece] = Image.open(
                f"Images/{ self.pieces_map[piece]}.png")
Exemple #2
0
    def vips_thumbnail(
        self, width: int, height: int, **loader_options
    ) -> VIPSImage:
        """Get VIPS thumbnail using vips shrink-on-load features."""

        filename = self.vips_filename_with_options(
            str(self.format.path),
            **loader_options
        )

        image = cached_vips_file(self.format)
        if image.interpretation in ("grey16", "rgb16"):
            # Related to https://github.com/libvips/libvips/issues/1941 ?
            return VIPSImage.thumbnail(
                filename, width, height=height,
                size=VIPSSize.FORCE, linear=True
            ).colourspace(image.interpretation)

        return VIPSImage.thumbnail(
            filename, width, height=height, size=VIPSSize.FORCE
        )
Exemple #3
0
    def Render(self):

        self.render_status = 'starting'

        self.render_start_time = datetime.datetime.utcnow()

        p = Popen(
            [
                self.ffmpeg,
                '-loglevel',
                'panic',
                '-s',
                '{}x{}'.format(self.output_raster_width,
                               self.output_raster_height),
                '-pix_fmt',
                'yuvj420p',
                '-y',
                '-f',
                'image2pipe',
                '-vcodec',
                'mjpeg',
                '-r',
                str(self.fps),
                '-i',
                '-',
                '-r',
                str(self.fps),
                '-f',
                'mp4',
                '-vcodec',
                'libx264',
                '-preset',
                'fast',
                # '-crf', '26',
                self.output_file_name + '.mp4'
            ],
            stdin=PIPE)

        if self.prores_mez:
            p_prores = Popen([
                self.ffmpeg, '-loglevel', 'panic', '-s', '1920x1080',
                '-pix_fmt', 'yuvj420p', '-y', '-f', 'image2pipe', '-vcodec',
                'mjpeg', '-r', self.fps, '-i', '-', '-r', self.fps, '-f',
                'mov', '-vcodec', 'prores', '-profile:v', '3', '-aspect',
                '16:9', '-y', self.output_file_name + '.mov'
            ],
                             stdin=PIPE)

        self.render_status = 'rendering'

        for frame in range(self.total_frames):

            gc.collect()

            begin_scale = 1
            diff_increments_zoom = 0

            zoom = begin_scale - (diff_increments_zoom * frame)

            y_total = 0

            # at 1 zoom, it's (5184 - 1920) / 79 frames...  41 pixels
            # at .45 zoom, it's ((5184 *.45) - 1920) / 79 frames...  5 pixels (413/79 total)

            resize_width = int(self.original_image_width * zoom)
            resize_height = int(self.original_image_height * zoom)

            if self.image_lib == 'vips':

                image_resize = VImage.thumbnail(self.file_path, resize_height)
                image_resize.copy(xoffset=int(x_total), yoffset=int(y_total))

                # output = image_resize.crop(int(x_total), int(y_total), (self.output_raster_width + int(x_total)), (self.output_raster_height + int(y_total)))
                output = image_resize.crop(0, 0, (self.output_raster_width),
                                           (self.output_raster_height))
                data = output.write_to_buffer('.JPEG', Q=95)
                image_bytes = PImage.open(io.BytesIO(data))
                image_bytes.save(p.stdin, 'JPEG')

                image_resize = VImage.thumbnail(
                    self.file_path, (zoom * self.original_image_width))
                image_resize.copy(xoffset=int(x_total), yoffset=int(y_total))
                output = image_resize.crop(0, 0, self.output_raster_width,
                                           self.output_raster_height)
                data = output.write_to_buffer('.JPEG', Q=95)
                image_bytes = PImage.open(io.BytesIO(data))
                image_bytes.save(p.stdin, 'JPEG')

            if self.image_lib == 'pillow':
                image_resize = self.original_image.resize(
                    (resize_width, resize_height), resample=PImage.BICUBIC)
                image_offset = PImageChops.offset(image_resize,
                                                  xoffset=int(0),
                                                  yoffset=int(y_total))
                image = image_offset.crop((0, 0, self.output_raster_width,
                                           self.output_raster_height))

                image.save(p.stdin, 'JPEG')
                # image.save(p_prores.stdin, 'JPEG')

            if self.image_lib == 'cv':

                _top = (self.output_raster_height - self.original_image_height)

                _left = (self.output_raster_width - self.original_image_width)

                top = int(_top / 2)
                bottom = _top - top
                left = int(_left / 2)
                right = _left - left

                color = [255, 255, 255]

                constant = cv2.copyMakeBorder(self.original_image,
                                              top,
                                              bottom,
                                              left,
                                              right,
                                              cv2.BORDER_CONSTANT,
                                              value=color)

                from_pil = PImage.fromarray(constant)

                from_pil.save(p.stdin, 'JPEG')

                # from_pil.show()

                if self.prores_mez:
                    from_pil.save(p_prores.stdin, 'JPEG')

            self.render_status_update()

            # https://stackoverflow.com/questions/13294919/can-you-stream-images-to-ffmpeg-to-construct-a-video-instead-of-saving-them-t
            # For anyone who stumbles upon this in the future, replacing 'mjpeg' with 'png' and 'JPEG' with 'PNG' worked for me to use png.
            # python 3.6 https://stackoverflow.com/questions/40108816/python-running-as-windows-service-oserror-winerror-6-the-handle-is-invalid

        p.stdin.close()
        p.wait()

        gc.collect()

        self.time_end = datetime.datetime.utcnow()
        seconds_delta = (self.time_end -
                         self.render_start_time).total_seconds()
        print('Render Complete. {} minutes'.format(seconds_delta / 60))
        self.render_status = 'done'