Change image with mouse & keyboard in Pygame By albro

in Programming & Dev2 years ago

Change image with mouse & keyboard in Pygame

In this part, I'll talk about images and sounds and tell how I use them in the program. I'll also tell you how to move the image with the mouse and zoom it in and out. I do all this with pygame methods. So let's start working soon.

Load Images

Images can be loaded and saved using the pyagme.image module. The load method loads an image from the file system and returns a Surface object. The convert method optimizes the image format and makes drawing the image faster:

img = pygame.image.load('hive.gif')
img.convert()

The image we use must be in the same folder as the program. The get_rect() method returns a Rect object from an image. In the example below, only the size is set and the image position is set to (0, 0). In the second line, I set the center of the Rect to the center of the page:

rect = img.get_rect()
rect.center = w//2, h//2

We use 3 objects to work with images:

  • screen object: This object is a Surface object that represents the application window.
  • img object: It's a Surface object that is used to display the image.
  • rect object: It's a Rect object. This object is a rectangle containing the image. (Because the images may not have smooth corners and actually have complex shapes, we place it in a surrounding or enclosing rectangle.)

I color the background gray. Then I draw the image in the window, draw a red rectangle around it, and finally update the page with update to show all the changes:

screen.fill(GRAY)
screen.blit(img, rect)
pygame.draw.rect(screen, RED, rect, 1)
pygame.display.update()

The complete code to display the image is below:

import pygame,sys
from pygame.locals import *
RED = (255, 0, 0)
GRAY = (150, 150, 150)
pygame.init()
w, h = 640, 300
screen = pygame.display.set_mode((w, h))
running = True
img = pygame.image.load('hive.gif')
img.convert()
rect = img.get_rect()
rect.center = w//2, h//2
while running:
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False
    screen.fill(GRAY)
    screen.blit(img, rect)
    pygame.draw.rect(screen, RED, rect, 1)
    pygame.display.update()
pygame.quit()

By running the above code, the following image will be displayed:

load image

Move the image with the mouse

At the beginning of the program, I define a boolean variable named moving. If the mouse button is pressed and the mouse is inside the image, I set it to True:

elif event.type == MOUSEBUTTONDOWN and rect.collidepoint(event.pos):
    moving = True

If the mouse button is released, I set moving to False again:

elif event.type == MOUSEBUTTONUP:
    moving = False

When the mouse moves, and moving is True, then I move the image according to the relative movement amount (event.rel):

elif event.type == MOUSEMOTION and moving:
    rect. move_ip(event.rel)

I move the following image:

Move The Image

import pygame, sys
from pygame.locals import *
RED = (255, 0, 0)
GRAY = (150, 150, 150)
pygame.init()
w, h = 640, 400
screen = pygame.display.set_mode((w, h))
running = True
img = pygame.image.load('hive.gif')
img.convert()
rect = img.get_rect()
rect.center = w//2, h//2
moving = False
while running:
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False        
        elif event.type == MOUSEBUTTONDOWN and rect.collidepoint(event.pos):
            moving = True
        elif event.type == MOUSEBUTTONUP:
            moving = False
        elif event.type == MOUSEMOTION and moving:
            rect.move_ip(event.rel)        
    screen.fill(GRAY)
    screen.blit(img, rect)
    pygame.draw.rect(screen, RED, rect, 1)
    pygame.display.update()
pygame.quit()

Rotate and resize the image

The pygame.transform module provides methods for resizing, rotating images. To modify the img image, I store the original image in a variable called img0:

img0 = pygame.image.load(path)
img0.convert()

To show the rectangle image, I add a green border to the main image:

rect0 = img0.get_rect()
pygame.draw.rect(img0, GREEN, rect0, 1)

Then I center the image on the screen:

center = w//2, h//2
img = img0
rect = img.get_rect()
rect.center = center

First, I define the global scale and angle variables:

angle = 0
scale = 1

I use the R key to increase the rotation of the image by 10 degrees. If you press the SHIFT key, the degree of rotation decreases. With the rotozoom() function, rotation and resizing can be used together. We always change the main image (img0). Rotating or resizing the image too much will reduce its quality:

if event.type == KEYDOWN:
    if event.key == K_r:
        if event.mod & KMOD_SHIFT:
            angle -= 10
        else:
            angle += 10
        img = pygame.transform.rotozoom(img0, angle, scale)

We use the S key to increase the amount of resizing. Each time you press the S key, we will increase the size by ten percent. If you press the SHIFT key, the amount of resizing will decrease.

elif event.key == K_s:
    if event.mod & KMOD_SHIFT:
        scale /= 1.1
    else:
        scale *= 1.1
    img = pygame.transform.rotozoom(img0, angle, scale)

As the image changes shape, the enclosing rectangle also changes its size. The image is re-centered:

rect = img.get_rect()
rect.center = center

Return the image to the original state

To return the image to its original state, I use the O key:

elif event.key == K_o:
    img = img0
    angle = 0
    scale = 1

Rotate the image

I use the H key to rotate the image horizontally:

elif event.key == K_h:
    img = pygame.transform.flip(img, True, False)

And I use the V key to rotate the image vertically:

elif event.key == K_v:
    img = pygame.transform.flip(img, False, True)

Image edge detection with Laplacian

The laplacian function helps us to identify the edges of an image:

elif event.key == K_l:
    img = pygame.transform.laplacian(img)

The image is below:

Laplacian

The scale2x function doubles the size of a pixel:

elif event.key == K_2:
    img = pygame.transform.scale2x(img)

scale2x

Change the shape of the image with the mouse

In this section, I show how to use the mouse to change the size and rotation of an image. First, I enter the math module:

import math

At the beginning, I save the initial position of the mouse:

mouse = pygame.mouse.get_pos()

When the mouse moves, I update the mouse position and calculate the x and y coordinates relative to the center of the image. I also get the distance from the mouse to the center, d:

elif event.type == MOUSEMOTION:
    mouse = event.pos
    x = mouse[0] - center[0]
    y = mouse[1] - center[1]
    d = math.sqrt(x ** 2 + y ** 2)

The mathematical function atan2(y, x) allows to obtain the rotation angle. To use this function, we need to convert radians to degrees. Using d, I calculate the size of the scale:

angle = math.degrees(-math. atan2(y, x))
scale = abs(5 * d / w)
img = pygame.transform.rotozoom(img0, angle, scale)
rect = img.get_rect()
rect.center = center

Finally, to draw the deformed image, first I paint the background with the desired color (gray), then I draw the deformed image in the window and draw a red rectangle around it. To create visual effects when changing the shape of the image with the mouse, I do the following two things:

  1. I draw a green line between the center of the image and the mouse position.
  2. I place two circles, one in the center of the image and the other in the mouse position.
screen.fill(GRAY)
screen.blit(img, rect)
pygame.draw.rect(screen, RED, rect, 1)
pygame.draw.line(screen, GREEN, center, mouse, 1)
pygame.draw.circle(screen, RED, center, 6, 1)
pygame.draw.circle(screen, RED, mouse, 6, 1)
pygame.display.update()

Look carefully at the image below.

Change the shape of the image with the mouse

import pygame
import math, sys, os
from pygame.locals import *
RED = (255, 0, 0)
GREEN = (0, 255, 0)
GRAY = (150, 150, 150)
pygame.init()
w, h = 640, 400
screen = pygame.display.set_mode((w, h))
running = True
module = sys.modules['__main__']
path, name = os.path.split(module.__file__)
path = os.path.join(path, 'hiverocket.png')
img0 = pygame.image.load(path)
img0. convert()
rect0 = img0.get_rect()
pygame.draw.rect(img0, GREEN, rect0, 1)
center = w//2, h//2
img = img0
rect = img.get_rect()
rect.center = center
angle = 0
scale = 1
mouse = pygame.mouse.get_pos()
while running:
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False
        if event.type == KEYDOWN:
            if event.key == K_r:
                if event.mod & KMOD_SHIFT:
                    angle -= 10
                else:
                    angle += 10
                img = pygame.transform.rotozoom(img0, angle, scale)
            elif event.key == K_s:
                if event.mod & KMOD_SHIFT:
                    scale /= 1.1
                else:
                    scale *= 1.1
                img = pygame.transform.rotozoom(img0, angle, scale)
            elif event.key == K_o:
                img = img0
                angle = 0
                scale = 1
            elif event.key == K_h:
                img = pygame.transform.flip(img, True, False)
            elif event.key == K_v:
                img = pygame.transform.flip(img, False, True)
            elif event.key == K_l:
                img = pygame.transform.laplacian(img)
            elif event.key == K_2:
                img = pygame.transform.scale2x(img)
            rect = img.get_rect()
            rect.center = center
        elif event.type == MOUSEMOTION:
            mouse = event.pos
            x = mouse[0] - center[0]
            y = mouse[1] - center[1]
            d = math.sqrt(x ** 2 + y ** 2)
            angle = math.degrees(-math. atan2(y, x))
            scale = abs(5 * d / w)
            img = pygame.transform.rotozoom(img0, angle, scale)
            rect = img.get_rect()
            rect.center = center
    screen.fill(GRAY)
    screen.blit(img, rect)
    pygame.draw.rect(screen, RED, rect, 1)
    pygame.draw.line(screen, GREEN, center, mouse, 1)
    pygame.draw.circle(screen, RED, center, 6, 1)
    pygame.draw.circle(screen, RED, mouse, 6, 1)
    pygame.display.update()
pygame.quit()
Sort:  

https://leofinance.io/threads/albro/re-leothreads-rvxfusnk
The rewards earned on this comment will go directly to the people ( albro ) sharing the post on LeoThreads,LikeTu,dBuzz.

Congratulations!


You have obtained a vote from CHESS BROTHERS PROJECT

✅ Good job. Your post has been appreciated and has received support from CHESS BROTHERS ♔ 💪


♟ We invite you to use our hashtag #chessbrothers and learn more about us.

♟♟ You can also reach us on our Discord server and promote your posts there.

♟♟♟ Consider joining our curation trail so we work as a team and you get rewards automatically.

♞♟ Check out our @chessbrotherspro account to learn about the curation process carried out daily by our team.


🥇 If you want to earn profits with your HP delegation and support our project, we invite you to join the Master Investor plan. Here you can learn how to do it.


Kindly

The CHESS BROTHERS team

Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!

Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).

You may also include @stemsocial as a beneficiary of the rewards of this post to get a stronger support. 
 

Congratulations @albro! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You distributed more than 300 upvotes.
Your next target is to reach 400 upvotes.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Check out our last posts:

HiveBuzz Women's World Cup Contest - Collect Badges and Prizes - Thousands of HIVE, Tokens or NFTs to be won!
Our Hive Power Delegations to the June PUM Winners
Yearly Authors Challenge Status