Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _update_foreground(self, pil_image, pos=CENTER, resize=True):
"""Show a PIL image on the foreground.
Only once is bufferized to avoid memory leak.
"""
image_name = id(pil_image)
image_size_max = (2 * self.surface.get_size()[1] // 3, 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)
return self.surface.blit(image, self._pos_map[pos](image))
def concatenate_pictures_PIL(portrait, pictures, footer_texts, bg_color, text_color, footer_fonts, inter_width=None):
""" Merge up to 4 PIL images.
"""
with timeit("Create final image with PIL"):
new_width, new_height, inter_width = get_pics_layout_size(pictures, portrait, inter_width)
matrix = Image.new('RGBA', (new_width, new_height))
# Consider that the photo are correctly ordered
offset_generator = get_pics_layout_offset(pictures, portrait, inter_width)
for i in range(len(pictures)):
matrix.paste(pictures[i], next(offset_generator))
final_width, final_height, matrix_width, matrix_height, footer_size = get_final_image_dimensions(
portrait, footer_texts)
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:
draw_footer_text(final_image, portrait, footer_texts, footer_fonts, footer_size, text_color)
return final_image
def concatenate_pictures_opencv(portrait, pictures, footer_texts, bg_color, text_color, footer_fonts, inter_width=None):
""" Merge up to 4 PIL images using opencv to manipulate the images.
"""
with timeit("Create final image with opencv"):
matrix_raw_width, matrix_raw_height, inter_width = get_pics_layout_size(pictures, portrait, inter_width)
final_width, final_height, matrix_width, matrix_height, footer_size = get_final_image_dimensions(
portrait, footer_texts)
offset_generator = get_pics_layout_offset(pictures, portrait, inter_width)
with timeit("Init final image with background"):
pics_scaling_factor = min(matrix_width / matrix_raw_width, matrix_height / matrix_raw_height)
pics_x_offset = int(matrix_width - matrix_raw_width * pics_scaling_factor) // 2
pics_y_offset = int(matrix_height - matrix_raw_height * pics_scaling_factor) // 2
final_image = new_image_with_background_opencv(final_width, final_height, bg_color)
with timeit("Layout pictures matrix"):
# Consider that the photo are correctly ordered
for i in range(len(pictures)):
cv_pic = np.array(pictures[i].convert('RGB'))
cv_pic = cv2.resize(cv_pic, None, fx=pics_scaling_factor,
fy=pics_scaling_factor, interpolation=cv2.INTER_AREA)
(h, w) = cv_pic.shape[:2]
x_offset, y_offset = next(offset_generator)
x_offset, y_offset = pics_x_offset + \
int(pics_scaling_factor * x_offset), pics_y_offset + int(pics_scaling_factor * y_offset)
self._rect.width // 5 - 2 * self._text_border,
self._rect.height * 0.3 - 2 * self._text_border)
else:
rect = pygame.Rect(self._rect.width // 2 + self._text_border, self._text_border,
self._rect.width // 5 - 2 * self._text_border,
self._rect.height * 0.3 - 2 * self._text_border)
self._write_text(text, rect)
def paint(self, screen):
Background.paint(self, screen)
if self.arrow_location != ARROW_HIDDEN:
screen.blit(self.right_arrow, self.right_arrow_pos)
screen.blit(self.left_arrow, self.left_arrow_pos)
class FinishedBackground(Background):
def __init__(self):
Background.__init__(self, "finished")
def resize_texts(self):
"""Update text surfaces.
"""
rect = pygame.Rect(self._rect.width * 0.3, self._rect.height * 0.6 - self._text_border,
self._rect.width * 0.4, self._rect.height * 0.4)
Background.resize_texts(self, rect)
class OopsBackground(Background):
def __init__(self):
Background.__init__(self, "oops")
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])
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])
def _build_texts(self, image):
"""Draw texts on a PIL image (PIL is used instead of OpenCV
because it is able to draw any fonts without ext).
:param image: PIL.Image instance
:type image: object
"""
offset_generator = self._iter_texts_rects()
draw = ImageDraw.Draw(image)
for text, font_name, color, align in self._texts:
text_x, text_y, max_width, max_height = next(offset_generator)
if not text: # Empty string: go to next text position
continue
# Use PIL to draw text because better support for fonts than OpenCV
font = fonts.get_pil_font(text, font_name, max_width, max_height)
_, text_height = font.getsize(text)
(text_width, _baseline), (offset_x, offset_y) = font.font.getsize(text)
if align == self.CENTER:
text_x += (max_width - text_width) // 2
elif align == self.RIGHT:
text_x += (max_width - text_width)
draw.text((text_x - offset_x // 2,
text_y + (max_height - text_height) // 2 - offset_y // 2),
text, color, font=font)
def build_overlay(self, size, text, alpha):
"""Return a PIL image with the given text that can be used
as an overlay for the camera.
"""
image = Image.new('RGBA', size)
draw = ImageDraw.Draw(image)
txt_width = size[0] + 1
i = 10
while txt_width > size[0]:
font = ImageFont.truetype(fonts.get_filename("Amatic-Bold.ttf"), size[1] * i // 10)
txt_width, txt_height = draw.textsize(text, font=font)
i -= 1
position = ((size[0] - txt_width) // 2, (size[1] - txt_height) // 2 - size[1] // 10)
draw.text(position, text, (255, 255, 255, alpha), font=font)
return image
def build_overlay(self, size, text, alpha):
"""Return a PIL image with the given text that can be used
as an overlay for the camera.
"""
image = Image.new('RGBA', size)
draw = ImageDraw.Draw(image)
font = fonts.get_pil_font(text, fonts.CURRENT, 0.9 * size[0], 0.9 * size[1])
txt_width, txt_height = draw.textsize(text, font=font)
position = ((size[0] - txt_width) // 2, (size[1] - txt_height) // 2 - size[1] // 10)
draw.text(position, text, (255, 255, 255, alpha), font=font)
return image
def draw_footer_text(final_image, portrait, footer_texts, footer_fonts, footer_size, text_color):
"""Draw footer text on final image.
"""
final_width, final_height = final_image.size
draw = ImageDraw.Draw(final_image)
# Footer 1
name_font = ImageFont.truetype(fonts.get_filename(footer_fonts[0]), int(2 / 3. * footer_size))
name_width, name_height = draw.textsize(footer_texts[0], font=name_font)
footer_x = (final_width - name_width) // 2 if portrait else final_width // 4 - name_width // 2
footer_y = final_height - footer_size - 100 if portrait else final_height - (footer_size + name_height) // 2 - 50
draw.text((footer_x, footer_y), footer_texts[0], text_color, font=name_font)
# Footer 2
date_font = ImageFont.truetype(fonts.get_filename(footer_fonts[-1]), int(1 / 3. * footer_size))
date_width, date_height = draw.textsize(footer_texts[1], font=date_font)
footer_x = (final_width - date_width) // 2 if portrait else 3 * final_width // 4 - date_width // 2
footer_y = final_height - footer_size + 300 if portrait else final_height - (footer_size + date_height) // 2 - 50
draw.text((footer_x, footer_y), footer_texts[1], text_color, font=date_font)