Пример #1
0
 def get_rect(self):
     """Return a Rect object (as defined in pygame) for resizing preview and images
     in order to fit to the defined window.
     """
     rect = self._window.get_rect()
     res = sizing.new_size_keep_aspect_ratio(self.resolution,
                                             (rect.width - 2 * self._border, rect.height - 2 * self._border))
     return pygame.Rect(rect.centerx - res[0] // 2, rect.centery - res[1] // 2, res[0], res[1])
Пример #2
0
def get_pygame_image(name,
                     size=None,
                     antialiasing=True,
                     hflip=False,
                     vflip=False,
                     crop=False,
                     angle=0,
                     color=(255, 255, 255),
                     bg_color=None):
    """Return a Pygame image. If a size is given, the image is
    resized keeping the original image's aspect ratio.

    :param name: name of an image located in language folders
    :type name: str
    :param size: resize image to this size
    :type size: tuple
    :param antialiasing: use antialiasing algorithm when resize
    :type antialiasing: bool
    :param hflip: apply an horizontal flip
    :type hflip: bool
    :param vflip: apply a vertical flip
    :type vflip: bool
    :param crop: crop image to fit aspect ration of the size
    :type crop: bool
    :param angle: angle of rotation of the image
    :type angle: int

    :return: pygame.Surface with image
    :rtype: object
    """
    path = get_filename(name)
    if not size:
        image = pygame.image.load(path).convert()
    else:
        if osp.isfile(path):
            pil_image = Image.open(path)
        else:
            pil_image = Image.new('RGBA', size, (0, 0, 0, 0))

        if color != None:
            pil_image = set_picto_color(pil_image, color, bg_color)

        if crop:
            pil_image = pil_image.crop(
                sizing.new_size_by_croping_ratio(pil_image.size, size))
        pil_image = pil_image.resize(
            sizing.new_size_keep_aspect_ratio(pil_image.size, size),
            Image.ANTIALIAS if antialiasing else Image.NEAREST)

        image = pygame.image.fromstring(pil_image.tobytes(), pil_image.size,
                                        pil_image.mode)

    if hflip or vflip:
        image = pygame.transform.flip(image, hflip, vflip)
    if angle != 0:
        image = pygame.transform.rotate(image, angle)
    return image
Пример #3
0
 def _fit_to_resolution(self, image):
     """Resize and crop to fit the desired resolution.
     """
     # Same process as RPI camera (almost), this is for keeping
     # final rendering sizing (see pibooth.picutres.maker)
     image = image.resize(
         sizing.new_size_keep_aspect_ratio(image.size, self.resolution,
                                           'outer'))
     return image.crop(
         sizing.new_size_by_croping(image.size, self.resolution))
Пример #4
0
 def _fit_to_resolution(self, image):
     """Resize and crop to fit the desired resolution.
     """
     # Same process as RPI camera (almost), this is for keeping
     # final rendering sizing (see pibooth.picutres.maker)
     height, width = image.shape[:2]
     size = sizing.new_size_keep_aspect_ratio((width, height), self.resolution, 'outer')
     image = cv2.resize(image, size, interpolation=cv2.INTER_AREA)
     height, width = image.shape[:2]
     cropped = sizing.new_size_by_croping((width, height), self.resolution)
     return image[cropped[1]:cropped[3], cropped[0]:cropped[2]]
Пример #5
0
    def _post_process_capture(self, capture_path):
        gp_path = self._captures[capture_path]
        camera_file = gp.check_result(gp.gp_camera_file_get(
            self._cam, gp_path.folder, gp_path.name, gp.GP_FILE_TYPE_NORMAL))

        image = Image.open(io.BytesIO(memoryview(camera_file.get_data_and_size())))
        image = image.resize(sizing.new_size_keep_aspect_ratio(image.size, self.resolution, 'outer'), Image.ANTIALIAS)
        image = image.crop(sizing.new_size_by_croping(image.size, self.resolution))

        if self._capture_hflip:
            image = image.transpose(Image.FLIP_LEFT_RIGHT)
        image.save(capture_path)
        return image
Пример #6
0
def new_image_with_background(width, height, background):
    """Create a new image with the given background. The background can be
    a RGB color tuple ora PIL image.
    """
    if isinstance(background, (tuple, list)):
        return Image.new('RGB', (width, height), color=background)
    else:
        image = Image.new('RGB', (width, height))
        image.paste(
            background.resize(
                sizing.new_size_keep_aspect_ratio(background.size, image.size,
                                                  'outer')))
        return image
Пример #7
0
def get_image(name, size=None, antialiasing=True):
    """Return a Pygame image. If a size is given, the image is
    resized keeping the original image's aspect ratio.

    :param antialiasing: use antialiasing algorithm when resize
    """
    if not size:
        return pygame.image.load(get_filename(name)).convert()
    else:
        image = Image.open(get_filename(name))
        image = image.resize(
            sizing.new_size_keep_aspect_ratio(image.size, size),
            Image.ANTIALIAS if antialiasing else Image.NEAREST)
        return pygame.image.fromstring(image.tobytes(), image.size, image.mode)
Пример #8
0
    def _update_foreground(self, pil_image, pos=CENTER, resize=True):
        """Show a PIL image on the foreground.
        Only one is bufferized to avoid memory leak.
        """
        image_name = id(pil_image)

        if pos == self.FULLSCREEN:
            image_size_max = (self.surface.get_size()[0] * 0.9,
                              self.surface.get_size()[1] * 0.9)
        else:
            image_size_max = (self.surface.get_size()[0] * 0.48,
                              self.surface.get_size()[1])

        buff_size, buff_image = self._buffered_images.get(
            image_name, (None, None))
        if buff_image and image_size_max == buff_size:
            image = buff_image
        else:
            if resize:
                image = pil_image.resize(
                    sizing.new_size_keep_aspect_ratio(pil_image.size,
                                                      image_size_max),
                    Image.ANTIALIAS)
            else:
                image = pil_image
            image = pygame.image.frombuffer(image.tobytes(), image.size,
                                            image.mode)
            if self._current_foreground:
                self._buffered_images.pop(id(self._current_foreground[0]),
                                          None)
            LOGGER.debug("Add to buffer the image '%s'", image_name)
            self._buffered_images[image_name] = (image_size_max, image)

        self._current_foreground = (pil_image, pos, resize)

        if self.debug and resize:
            # Build rectangle around picture area for debuging purpose
            outlines = pygame.Surface(image_size_max, pygame.SRCALPHA, 32)
            pygame.draw.rect(outlines, pygame.Color(255, 0, 0),
                             outlines.get_rect(), 2)
            self.surface.blit(outlines, self._pos_map[pos](outlines))

        return self.surface.blit(image, self._pos_map[pos](image))
Пример #9
0
    def _get_preview_image(self):
        """Capture a new preview image.
        """
        rect = self.get_rect()
        if self._preview_compatible:
            cam_file = self._cam.capture_preview()
            image = Image.open(io.BytesIO(cam_file.get_data_and_size()))
            # Crop to keep aspect ratio of the resolution
            image = image.crop(sizing.new_size_by_croping_ratio(image.size, self.resolution))
            # Resize to fit the available space in the window
            image = image.resize(sizing.new_size_keep_aspect_ratio(image.size, (rect.width, rect.height), 'outer'))

            if self._preview_hflip:
                image = image.transpose(Image.FLIP_LEFT_RIGHT)
        else:
            image = Image.new('RGB', (rect.width, rect.height), color=(0, 0, 0))

        if self._overlay:
            image.paste(self._overlay, (0, 0), self._overlay)
        return image
Пример #10
0
def get_pygame_image(name,
                     size=None,
                     antialiasing=True,
                     hflip=False,
                     vflip=False,
                     crop=False):
    """Return a Pygame image. If a size is given, the image is
    resized keeping the original image's aspect ratio.

    :param name: name of an image located in language folders
    :type name: str
    :param size: resize image to this size
    :type size: tuple
    :param antialiasing: use antialiasing algorithm when resize
    :type antialiasing: bool
    :param hflip: apply an horizontal flip
    :type hflip: bool
    :param vflip: apply a vertical flip
    :type vflip: bool
    :param crop: crop image to fit aspect ration of the size
    :type crop: bool

    :return: pygame.Surface with image
    :rtype: object
    """
    if not size:
        image = pygame.image.load(get_filename(name)).convert()
    else:
        image = Image.open(get_filename(name))
        if crop:
            image = image.crop(
                sizing.new_size_by_croping_ratio(image.size, size))
        image = image.resize(
            sizing.new_size_keep_aspect_ratio(image.size, size),
            Image.ANTIALIAS if antialiasing else Image.NEAREST)
        image = pygame.image.fromstring(image.tobytes(), image.size,
                                        image.mode)

    if hflip or vflip:
        image = pygame.transform.flip(image, hflip, vflip)
    return image
Пример #11
0
    def _post_process_capture(self, capture_path):
        """Rework and return a Image object from file.
        """
        image, effect = self._captures[capture_path]

        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        # Crop to keep aspect ratio of the resolution
        height, width = image.shape[:2]
        cropped = sizing.new_size_by_croping_ratio((width, height), self.resolution)
        image = image[cropped[1]:cropped[3], cropped[0]:cropped[2]]
        # Resize to fit the resolution
        height, width = image.shape[:2]
        size = sizing.new_size_keep_aspect_ratio((width, height), self.resolution, 'outer')
        image = cv2.resize(image, size, interpolation=cv2.INTER_AREA)

        if self._capture_hflip:
            image = cv2.flip(image, 1)

        if effect != 'none':
            pass  # To be implemented

        cv2.imwrite(capture_path, cv2.cvtColor(image, cv2.COLOR_RGB2BGR))
        return Image.fromarray(image)
Пример #12
0
    def _post_process_capture(self, capture_path):
        """Rework and return a Image object from file.
        """
        gp_path, effect = self._captures[capture_path]
        camera_file = self._cam.file_get(gp_path.folder, gp_path.name, gp.GP_FILE_TYPE_NORMAL)
        if self.delete_internal_memory:
            LOGGER.debug("Delete capture '%s' from internal memory", gp_path.name)
            self._cam.file_delete(gp_path.folder, gp_path.name)
        image = Image.open(io.BytesIO(camera_file.get_data_and_size()))

        # Crop to keep aspect ratio of the resolution
        image = image.crop(sizing.new_size_by_croping_ratio(image.size, self.resolution))
        # Resize to fit the resolution
        image = image.resize(sizing.new_size_keep_aspect_ratio(image.size, self.resolution, 'outer'))

        if self._capture_hflip:
            image = image.transpose(Image.FLIP_LEFT_RIGHT)

        if effect != 'none':
            image = image.filter(getattr(ImageFilter, effect.upper()))

        image.save(capture_path)
        return image
Пример #13
0
def test_resize_original_small_outer():
    size = sizing.new_size_keep_aspect_ratio((600, 200), (900, 600), 'outer')
    assert size == (1800, 600)
Пример #14
0
def concatenate_pictures_portrait(pictures,
                                  footer_texts,
                                  bg_color,
                                  text_color,
                                  inter_width=None):
    """
    Merge up to 4 PIL images in portrait orientation.

      +---------+     +---------+     +---+-+---+     +---------+
      |         |     |   +-+   |     |   |1|   |     | +-+ +-+ |
      |         |     |   |1|   |     |   +-+   |     | |1| |2| |
      |   +-+   |     |   +-+   |     |   +-+   |     | +-+ +-+ |
      |   |1|   |     |         |     |   |2|   |     |         |
      |   +-+   |     |   +-+   |     |   +-+   |     | +-+ +-+ |
      |         |     |   |2|   |     |   +-+   |     | |3| |4| |
      |         |     |   +-+   |     |   |3|   |     | +-+ +-+ |
      +---------+     +---------+     +---+-+---+     +---------+
    """
    widths, heights = zip(*(i.size for i in pictures))

    # starting here we consider that all the images have the same height and widths
    if inter_width is None:
        inter_width = max(heights) // 20

    if len(pictures) == 1:
        new_width = max(widths) + inter_width * 2
        new_height = max(heights) + inter_width * 2
    elif len(pictures) == 2:
        new_width = max(widths) + inter_width * 2
        new_height = max(heights) * 2 + inter_width * 3
    elif len(pictures) == 3:
        new_width = max(widths) + inter_width * 2
        new_height = max(heights) * 3 + inter_width * 4
    elif len(pictures) == 4:
        new_width = max(widths) * 2 + inter_width * 3
        new_height = max(heights) * 2 + inter_width * 3
    else:
        raise ValueError("List of max 4 pictures expected, got {}".format(
            len(pictures)))

    matrix = Image.new('RGBA', (new_width, new_height))

    x_offset = inter_width
    y_offset = inter_width

    # Consider that the photo are correctly ordered
    matrix.paste(pictures[0], (x_offset, y_offset))
    if len(pictures) == 2:
        y_offset += (pictures[0].size[1] + inter_width)
        matrix.paste(pictures[1], (x_offset, y_offset))
    elif len(pictures) == 3:
        y_offset += (pictures[0].size[1] + inter_width)
        matrix.paste(pictures[1], (x_offset, y_offset))
        y_offset += (pictures[1].size[1] + inter_width)
        matrix.paste(pictures[2], (x_offset, y_offset))
    elif len(pictures) == 4:
        x_offset += (pictures[0].size[0] + inter_width)
        matrix.paste(pictures[1], (x_offset, y_offset))
        y_offset += (pictures[1].size[1] + inter_width)
        x_offset = inter_width
        matrix.paste(pictures[2], (x_offset, y_offset))
        x_offset += (pictures[2].size[0] + inter_width)
        matrix.paste(pictures[3], (x_offset, y_offset))

    final_width, final_height = 2400, 3600
    if not footer_texts[0] and not footer_texts[1]:
        matrix_width, matrix_height = final_width, final_height
        footer_size = 0
    else:
        matrix_width, matrix_height = 2400, 3000
        footer_size = 600

    matrix = matrix.resize(
        sizing.new_size_keep_aspect_ratio(matrix.size,
                                          (matrix_width, matrix_height)),
        Image.ANTIALIAS)
    final_image = new_image_with_background(final_width, final_height,
                                            bg_color)
    final_image.paste(matrix,
                      ((final_width - matrix.size[0]) // 2,
                       (final_height - footer_size - matrix.size[1]) // 2),
                      mask=matrix)

    if footer_size:
        # Text part
        draw = ImageDraw.Draw(final_image)

        # Footer 1
        name_font = ImageFont.truetype(fonts.get_filename("Amatic-Bold.ttf"),
                                       int(2 / 3. * footer_size))
        name_width, name_height = draw.textsize(footer_texts[0],
                                                font=name_font)
        footer_x = (final_width - name_width) // 2
        footer_y = final_height - footer_size - 100
        draw.text((footer_x, footer_y),
                  footer_texts[0],
                  text_color,
                  font=name_font)

        # Footer 2
        date_font = ImageFont.truetype(
            fonts.get_filename("AmaticSC-Regular.ttf"),
            int(1 / 3. * footer_size))
        date_width, date_height = draw.textsize(footer_texts[1],
                                                font=date_font)
        footer_x = (final_width - date_width) // 2
        footer_y = final_height - footer_size + 300
        draw.text((footer_x, footer_y),
                  footer_texts[1],
                  text_color,
                  font=date_font)

    return final_image
Пример #15
0
def test_resize_original_big_inner():
    size = sizing.new_size_keep_aspect_ratio((1000, 1200), (800, 600))
    assert size == (500, 600)
Пример #16
0
def test_resize_original_big_outer():
    size = sizing.new_size_keep_aspect_ratio((1000, 1200), (800, 600), 'outer')
    assert size == (800, 960)
Пример #17
0
def test_resize_original_small_inner():
    size = sizing.new_size_keep_aspect_ratio((600, 200), (900, 600))
    assert size == (900, 300)