# How to rotate an image in pygame without losing quality or increasing size or moving position

I am trying to make a game in which I place a spaceship (its an image I downloaded) in the center and then rotate it on its place. However, when I use pygame.transform.rotate(), it rotates the image and changes its location and keeps on increasing its size. I have tried pygame.transform.rotozoom but even when I used scale 1, it didn't show any difference. And also when it rotates and blits the image onto the screen the image severely loses its quality. Pleaseee helpp!!

• Could you update the question and add a screenshot or two (i.e. the original image, the effect when it's in the game and the effect when it's rotated), and the relevant part of the code? – Alexandre Vaillancourt Jul 29 '16 at 14:45

## Maintaining quality

When you're rotating the image using pygame.transform.rotate(), pygame creates a new Surface with your rotated image on. By doing this your image lose some information and therefore some quality. That's why it's always practical to rotate the original image and not a rotated copy. In code it'll look something like this:

class Player(pygame.sprite.Sprite):

def __init__(self, pos=(0, 0)):
super(Player, self).__init__()
self.image = self.original_image  # This will reference our rotated image.
self.rect = self.image.get_rect().move(pos)
self.angle = 0

def update(self):
self.image = pygame.transform.rotate(self.original_image, self.angle)
self.angle += 1 % 360  # Value will reapeat after 359. This prevents angle to overflow.


## Why the image changes size

Surfaces in pygame can't actually be rotated; they have a horizontal width and a vertical height. When you load your image pygame creates a Surface which has a horizontal width and a vertical height equal to your image. When you rotate your image 45 degrees pygame have to create a new Surface where your original image fits. The new Surface's horizontal width and vertical height has to be the images hypothenuse to be able to fit the image.

As you see, the Surface is the biggest when the hypothenuse (the turquoise line) is vertical (or horizontal). This is supposed to be, otherwise your image wouldn't fit. If the problem you're having is about collision detection I'd recommend you to try other forms of collision detection like circular, or keep using rectangular but minimize it's size.

## Keep the image on the same position

To prevent the image from moving I usually position the image by its center. So after each rotation I move its new center to its previous center.

def update(self):
self.image = pygame.transform.rotate(self.original_image, self.angle)
self.angle += 1 % 360  # Value will reapeat after 359. This prevents angle to overflow.
x, y = self.rect.center  # Save its current center.
self.rect = self.image.get_rect()  # Replace old rect with new rect.
self.rect.center = (x, y)  # Put the new rect's center at old center.


## Full code

import pygame

class Player(pygame.sprite.Sprite):

def __init__(self, pos=(0, 0), size=(200, 200)):
super(Player, self).__init__()
self.original_image = pygame.Surface(size)
pygame.draw.line(self.original_image, (255, 0, 255), (size[0] / 2, 0), (size[0] / 2, size[1]), 3)
pygame.draw.line(self.original_image, (0, 255, 255), (size[1], 0), (0, size[1]), 3)
self.image = self.original_image
self.rect = self.image.get_rect()
self.rect.center = pos
self.angle = 0

def update(self):
self.image = pygame.transform.rotate(self.original_image, self.angle)
self.angle += 1 % 360  # Value will reapeat after 359. This prevents angle to overflow.
x, y = self.rect.center  # Save its current center.
self.rect = self.image.get_rect()  # Replace old rect with new rect.
self.rect.center = (x, y)  # Put the new rect's center at old center.

def main():
player = Player(pos=(200, 200))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
raise SystemExit

player.update()
screen.fill((255, 255, 255))
screen.blit(player.image, player.rect)
pygame.display.update()

if __name__ == '__main__':
pygame.init()
screen = pygame.display.set_mode((400, 400))
main()


I don't know pygame, but here are some ways to fix some of your issues.

However, when I use pygame.transform.rotate(), it rotates the image and changes its location and keeps on increasing its size.

This is typically caused because you have other transformations that are applied, i.e. if you have a scale applied before you do the rotation.