0

How can I take a screenshot of a certain part of the pygame screen?

For example, this is my screen

screen

and I want to take a screenshot of the area between the top-left dot, and the bottom-right dot (the coordinate are (20, 100), (480, 480), and the whole display is 500x50).

This is my best result so far (but it's still not good):

def screenshot(obj, file_name, position, size):
    img = pygame.Surface(size_f)
    img.blit(obj, (0, 0), (position, size))
    pygame.image.save(img, file_name)
...
...
...
screenshot(game, "test1.png", (0, 100), (500, 400))

screen

I added the black border to show the image border, because the image is white.

---------- EDIT ----------

with this function call

screenshot(game, "test1.png", (20, 100), (480, 400))

i'm getting a better result - now both the top and the left sides are ok, (because the top-left is the point where the x and y starts) but still - both the right and the bottom sides aren't good

i.imgur.com/prH2WOB.png


noam
  • 1
  • 3
  • 1
    Possible duplicate of [How to take screenshot of certain part of screen in Pygame](http://stackoverflow.com/questions/17267395/how-to-take-screenshot-of-certain-part-of-screen-in-pygame) – Tiger-222 Sep 17 '16 at 10:05
  • no, i've already tried this.. there is always padding around, because the selection is in the center (and not full-width) so I can't specify the exact coordinate with this method (from the link) – noam Sep 17 '16 at 10:26
  • But your code does work and does exactly what would be expected. It takes a screenshot from the coordinates you've given. What else are you trying to do? – Ted Klein Bergman Sep 17 '16 at 10:51
  • The top side is good, but the bottom, right and left sides, aren't good - there is like padding, and i'm trying to get result without any padding - like the top side. If there is no way to do that with PyGame, so maybe there is an easy way to do this in 2 steps - 1) the screenshot (what I already have) and 2) to cut the image with other python library. (I prefer a method with one step, but if PyGame doesn't provide this, so two-steps method is also fine) – noam Sep 17 '16 at 13:39
  • @noam I explained in further detail in the answer below. – Ted Klein Bergman Sep 19 '16 at 13:53

1 Answers1

2

Your function has an error (size_f is not defined) but otherwise it's working. The function

def screenshot(obj, file_name, position, size):
    img = pygame.Surface(size)
    img.blit(obj, (0, 0), (position, size))
    pygame.image.save(img, file_name)

takes the the topleft position and the size of the rectangle. You said yourself that the topleft red dot is at (20, 100), so the position argument should be at (20, 100) (that's why your second attempt fixes the padding to the left and top).

The bottomright point is determined by the size of the rectangle. We're trying to get from (20, 100)to (480, 480), so some quick math will give us the size:

width = 480 - 20 = 460
height = 480 - 100 = 380

Your function should give the right result if you do like this:

screenshot(game, "test1.png", (20, 100), (460, 380))

You could do this if you want to change the function to take two positions instead:

def screenshot(obj, file_name, topleft, bottomright):
    size = bottomright[0] - topleft[0], bottomright[1] - topleft[1]
    img = pygame.Surface(size)
    img.blit(obj, (0, 0), (topleft, size))
    pygame.image.save(img, file_name)

Here's an example demonstrating both functions:

import pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()


def screenshot(obj, file_name, position, size):
    img = pygame.Surface(size)
    img.blit(obj, (0, 0), (position, size))
    pygame.image.save(img, file_name)


def screenshot2(obj, file_name, topleft, bottomright):
    size = bottomright[0] - topleft[0], bottomright[1] - topleft[1]
    img = pygame.Surface(size)
    img.blit(obj, (0, 0), (topleft, size))
    pygame.image.save(img, file_name)

a = pygame.Surface((10, 10))
a.fill((255, 0, 0))


while 1:
    clock.tick(30)

    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_s:
                screenshot(screen, "test1.png", (20, 100), (460, 380))
                screenshot2(screen, "test2.png", (20, 100), (480, 480))
                print("PRINTED")
        elif event.type == pygame.QUIT:
            quit()

    screen.blit(a, (20, 100))
    screen.blit(a, (480, 480))
    pygame.display.update()
Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50