I would suggest adopting a slightly different approach presented here: How to set the pivot point (center of rotation) for pygame.transform.rotate()?
All you have to do to adjust this algorithm is scale the vector from the image center to the pivot point on the image by the zoom factor:
offset_center_to_pivot = pygame.math.Vector2(origin) - image_rect.center
offset_center_to_pivot = (pygame.math.Vector2(origin) - image_rect.center) * scale
The final function that rotates an image around a pivot point, zooms and blit
s the image might look like this:
def blitRotate(surf, original_image, origin, pivot, angle, scale):
image_rect = original_image.get_rect(topleft = (origin[0] - pivot[0], origin[1]-pivot[1]))
offset_center_to_pivot = (pygame.math.Vector2(origin) - image_rect.center) * scale
rotated_offset = offset_center_to_pivot.rotate(-angle)
rotated_image_center = (origin[0] - rotated_offset.x, origin[1] - rotated_offset.y)
rotozoom_image = pygame.transform.rotozoom(original_image, angle, scale)
rect = rotozoom_image.get_rect(center = rotated_image_center)
surf.blit(rotozoom_image, rect)
The scaling factor can also be specified separately for the x and y axis:
def blitRotate(surf, original_image, origin, pivot, angle, scale_x, scale_y):
image_rect = original_image.get_rect(topleft = (origin[0] - pivot[0], origin[1]-pivot[1]))
offset_center_to_pivot = pygame.math.Vector2(origin) - image_rect.center
offset_center_to_pivot.x *= scale_x
offset_center_to_pivot.y *= scale_y
rotated_offset = offset_center_to_pivot.rotate(-angle)
rotated_image_center = (origin[0] - rotated_offset.x, origin[1] - rotated_offset.y)
scaled_image = pygame.transform.smoothscale(original_image, (image_rect.width * scale_x, image_rect.height * scale_y))
rotozoom_image = pygame.transform.rotate(scaled_image, angle)
rect = rotozoom_image.get_rect(center = rotated_image_center)
surf.blit(rotozoom_image, rect)
See also Rotate surface
Minimal example:
repl.it/@Rabbid76/PyGame-RotateZoomPivot

import pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
def blitRotate(surf, original_image, origin, pivot, angle, scale):
image_rect = original_image.get_rect(topleft = (origin[0] - pivot[0], origin[1]-pivot[1]))
offset_center_to_pivot = (pygame.math.Vector2(origin) - image_rect.center) * scale
rotated_offset = offset_center_to_pivot.rotate(-angle)
rotated_image_center = (origin[0] - rotated_offset.x, origin[1] - rotated_offset.y)
rotozoom_image = pygame.transform.rotozoom(original_image, angle, scale)
rect = rotozoom_image.get_rect(center = rotated_image_center)
surf.blit(rotozoom_image, rect)
pygame.draw.rect (surf, (255, 0, 0), rect, 2)
try:
image = pygame.image.load('AirPlane.png')
except:
text = pygame.font.SysFont('Times New Roman', 50).render('image', False, (255, 255, 0))
image = pygame.Surface((text.get_width()+1, text.get_height()+1))
pygame.draw.rect(image, (0, 0, 255), (1, 1, *text.get_size()))
image.blit(text, (1, 1))
w, h = image.get_size()
angle, zoom = 0, 1
done = False
while not done:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pos = (screen.get_width()/2, screen.get_height()/2)
screen.fill(0)
blitRotate(screen, image, pos, (w/4, h/2), angle, zoom)
angle += 1
zoom += 0.01
if zoom > 5:
zoom = 1
pygame.draw.line(screen, (0, 255, 0), (pos[0]-20, pos[1]), (pos[0]+20, pos[1]), 3)
pygame.draw.line(screen, (0, 255, 0), (pos[0], pos[1]-20), (pos[0], pos[1]+20), 3)
pygame.draw.circle(screen, (0, 255, 0), pos, 7, 0)
pygame.display.flip()
pygame.quit()
exit()
Example 2:
repl.it/@Rabbid76/PyGame-RotateZoomPivot

import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
clock = pygame.time.Clock()
def blitRotateZoomXY(surf, original_image, origin, pivot, angle, scale_x, scale_y):
image_rect = original_image.get_rect(topleft = (origin[0] - pivot[0], origin[1]-pivot[1]))
offset_center_to_pivot = pygame.math.Vector2(origin) - image_rect.center
offset_center_to_pivot.x *= scale_x
offset_center_to_pivot.y *= scale_y
rotated_offset = offset_center_to_pivot.rotate(-angle)
rotated_image_center = (origin[0] - rotated_offset.x, origin[1] - rotated_offset.y)
scaled_image = pygame.transform.smoothscale(original_image, (image_rect.width * scale_x, image_rect.height * scale_y))
rotozoom_image = pygame.transform.rotate(scaled_image, angle)
rect = rotozoom_image.get_rect(center = rotated_image_center)
surf.blit(rotozoom_image, rect)
cannon = pygame.image.load('icon/cannon.png')
cannon_mount = pygame.image.load('icon/cannon_mount.png')
angle, zoom_x, zoom_y = -90, 1, 1
stage = 0
done = False
while not done:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pos = (screen.get_width()/3, screen.get_height()*3/4)
screen.fill((192, 192, 192))
blitRotateZoomXY(screen, cannon, pos, (33.5, 120), angle, zoom_x, zoom_y)
screen.blit(cannon_mount, (pos[0]-43, pos[1]-16))
pygame.display.flip()
if stage == 0:
angle += 1
if angle >= -30:
stage += 1
elif stage == 1:
zoom_y -= 0.05
if zoom_y <= 0.7:
stage += 1
elif stage == 2:
zoom_y += 0.05
if zoom_y >= 1:
stage += 1
elif stage == 3:
angle -= 1
if angle <= -90:
stage = 0
pygame.quit()
exit()