From 731ed2215683a009051ba22ea54d8ed2678f6d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laure=CE=B7t?= Date: Wed, 14 Dec 2022 10:22:19 +0100 Subject: [PATCH] feat: better blitRotate --- src/bodyparts/crown.py | 7 +------ src/bodyparts/ear.py | 6 +++--- src/bodyparts/eye.py | 7 +------ src/bodyparts/head.py | 7 +------ src/bodyparts/moustache.py | 6 +++--- src/bodyparts/mouth.py | 12 +++++------- src/utils.py | 23 +++++++++++++++++++---- 7 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/bodyparts/crown.py b/src/bodyparts/crown.py index b572dfe..c8844dd 100644 --- a/src/bodyparts/crown.py +++ b/src/bodyparts/crown.py @@ -30,10 +30,5 @@ class Crown: (self.env.size[0] / 3, self.env.size[1] / 3), ) - texture_pos = crown_pos - pg.Vector2( - texture_scaled.get_width() / 2, - texture_scaled.get_height() / 2, - ) - # draw texture - blitRotate(screen, texture_scaled, texture_pos, self.env.angle) + blitRotate(screen, texture_scaled, crown_pos, self.env.angle) diff --git a/src/bodyparts/ear.py b/src/bodyparts/ear.py index fd5b744..d3e41c9 100644 --- a/src/bodyparts/ear.py +++ b/src/bodyparts/ear.py @@ -36,7 +36,7 @@ class Ear: if self.side: # right moustache moustache_pos = landmark2vec(face_landmarks.landmark[LANDMARKS[0]], screen) - texture_pos = moustache_pos - pg.Vector2( + pivot = pg.Vector2( 3 * texture_scaled.get_width() / 4, 0.8 * texture_scaled.get_height(), ) @@ -44,10 +44,10 @@ class Ear: else: # left moustache moustache_pos = landmark2vec(face_landmarks.landmark[LANDMARKS[1]], screen) - texture_pos = moustache_pos - pg.Vector2( + pivot = pg.Vector2( texture_scaled.get_width() / 4, 0.8 * texture_scaled.get_height(), ) # draw texture - blitRotate(screen, texture_scaled, texture_pos, self.env.angle) + blitRotate(screen, texture_scaled, moustache_pos, self.env.angle, pivot) diff --git a/src/bodyparts/eye.py b/src/bodyparts/eye.py index ba2d221..0924abb 100644 --- a/src/bodyparts/eye.py +++ b/src/bodyparts/eye.py @@ -60,10 +60,5 @@ class Eye: (width, height), ) - texture_pos = iris_pos - pg.Vector2( - texture_scaled.get_width() / 2, - texture_scaled.get_height() / 2, - ) - # draw texture - blitRotate(screen, texture_scaled, texture_pos, angle) + blitRotate(screen, texture_scaled, iris_pos, angle) diff --git a/src/bodyparts/head.py b/src/bodyparts/head.py index 10a159b..860519f 100644 --- a/src/bodyparts/head.py +++ b/src/bodyparts/head.py @@ -41,10 +41,5 @@ class Head: self.env.size, ) - texture_pos = head_pos - pg.Vector2( - texture_scaled.get_width() / 2, - texture_scaled.get_height() / 2, - ) - # draw texture - blitRotate(screen, texture_scaled, texture_pos, self.env.angle) + blitRotate(screen, texture_scaled, head_pos, self.env.angle) diff --git a/src/bodyparts/moustache.py b/src/bodyparts/moustache.py index 8dcc513..5a542d1 100644 --- a/src/bodyparts/moustache.py +++ b/src/bodyparts/moustache.py @@ -36,7 +36,7 @@ class Moustache: if self.side: # right moustache moustache_pos = landmark2vec(face_landmarks.landmark[LANDMARKS[0]], screen) - texture_pos = moustache_pos - pg.Vector2( + pivot = pg.Vector2( texture_scaled.get_width(), texture_scaled.get_height() / 2, ) @@ -44,10 +44,10 @@ class Moustache: else: # left moustache moustache_pos = landmark2vec(face_landmarks.landmark[LANDMARKS[1]], screen) - texture_pos = moustache_pos - pg.Vector2( + pivot = pg.Vector2( 0, texture_scaled.get_height() / 2, ) # draw texture - blitRotate(screen, texture_scaled, texture_pos, self.env.angle) + blitRotate(screen, texture_scaled, moustache_pos, self.env.angle, pivot) diff --git a/src/bodyparts/mouth.py b/src/bodyparts/mouth.py index 35ee0e6..3e2d388 100644 --- a/src/bodyparts/mouth.py +++ b/src/bodyparts/mouth.py @@ -11,6 +11,7 @@ if TYPE_CHECKING: LANDMARKS = [78, 13, 308, 14] MIN_HEIGHT = 4 +MAX_HEIGHT = 40 class Mouth: @@ -33,14 +34,16 @@ class Mouth: mouth_right = landmark2vec(face_landmarks.landmark[LANDMARKS[2]], screen) height = (mouth_bottom - mouth_top).length() + height = min(height, MAX_HEIGHT) width = (mouth_right - mouth_left).length() - head_pos = (mouth_bottom + mouth_top) / 2 + mouth_pos = (mouth_bottom + mouth_top) / 2 if height < MIN_HEIGHT: height = MIN_HEIGHT texture = self.closed_texture else: + height *= 1.5 texture = self.texture texture_scaled = pg.transform.scale( @@ -48,10 +51,5 @@ class Mouth: (width, height), ) - texture_pos = head_pos - pg.Vector2( - texture_scaled.get_width() / 2, - texture_scaled.get_height() / 2, - ) - # draw texture - blitRotate(screen, texture_scaled, texture_pos, self.env.angle) + blitRotate(screen, texture_scaled, mouth_pos, self.env.angle) diff --git a/src/utils.py b/src/utils.py index cff2548..c2a0a1d 100644 --- a/src/utils.py +++ b/src/utils.py @@ -2,12 +2,27 @@ import numpy as np import pygame as pg from mediapipe.python.solutions.drawing_utils import _normalized_to_pixel_coordinates +# def blitRotate(surf, image, topleft, angle): +# """Rotate an image while drawing it.""" +# rotated_image = pg.transform.rotate(image, angle) +# new_rect = rotated_image.get_rect(center=image.get_rect(topleft=topleft).center) +# surf.blit(rotated_image, new_rect.topleft) -def blitRotate(surf, image, topleft, angle): - """Rotate an image while drawing it.""" + +# https://stackoverflow.com/questions/70819750/rotating-and-scaling-an-image-around-a-pivot-while-scaling-width-and-height-sep/70820034#70820034 +def blitRotate(surf, image, origin, angle, pivot=None): + + if pivot is None: + pivot = pg.math.Vector2(image.get_size()) / 2 + + image_rect = image.get_rect(topleft=(origin[0] - pivot[0], origin[1] - pivot[1])) + offset_center_to_pivot = pg.math.Vector2(origin) - image_rect.center + rotated_offset = offset_center_to_pivot.rotate(-angle) + rotated_image_center = (origin[0] - rotated_offset.x, origin[1] - rotated_offset.y) rotated_image = pg.transform.rotate(image, angle) - new_rect = rotated_image.get_rect(center=image.get_rect(topleft=topleft).center) - surf.blit(rotated_image, new_rect.topleft) + rect = rotated_image.get_rect(center=rotated_image_center) + + surf.blit(rotated_image, rect) def landmark2vec(landmark, screen):