Масштабирование Pygame от 28x28 пикселей до 420x420 - PullRequest
2 голосов
/ 14 мая 2019

Здравствуйте, я столкнулся с небольшой проблемой. Я пытаюсь создать графический интерфейс для набора данных Mnist, и мне нужно окно с размером 28x28 пикселей, однако это примерно 420x420 в пространстве экрана. Это означает, что каждый пиксель должен отображаться в 15 раз больше его исходного размера Мне также нужно рисовать на экране. Я пока не нашел ничего, что действительно работает.

Заранее спасибо. (Если вам нужны разъяснения, пожалуйста, просто оставьте комментарий)

Pygame версия 1.9.6

Python версия 3.6.7

1 Ответ

2 голосов
/ 15 мая 2019

Тривиальный ответ на это - просто масштабировать растровое изображение с pygame.transform.smoothscale(), а затем blit() на экране. Однако это масштабирование требует больших вычислительных ресурсов.

Довольно легко определить «пиксельный» спрайт, который масштабируется и позиционируется в зависимости от размера экрана. Когда для пикселя установлено значение (x,y), это просто переводится в масштабированное положение на экране.

Я параметризовал размер экрана и количество пикселей, чтобы легко масштабировать пиксели до необходимого значения.

Код использует список координат, чтобы нарисовать на экране группу пикселей-спрайтов.

import pygame
import sys

# Window size
WINDOW_WIDTH  = 420
WINDOW_HEIGHT = 420
FPS           = 60
PIXELS_WIDTH  = 28  # How many big-pixels vertically
PIXELS_HEIGHT = 28  # How many big-pixels horizontally
# background & colours
INKY_BLACK    = ( 28,  28,  58)
EGG_YELLOW    = (255, 233, 132)

class PixelSprite( pygame.sprite.Sprite ):
    def __init__( self, x, y, width=WINDOW_WIDTH//PIXELS_WIDTH, height=WINDOW_HEIGHT//PIXELS_HEIGHT ):
        pygame.sprite.Sprite.__init__( self )
        self.image  = pygame.Surface( ( width, height ), pygame.SRCALPHA )
        self.rect   = self.image.get_rect()
        self.rect.x = x * WINDOW_WIDTH  // PIXELS_WIDTH
        self.rect.y = y * WINDOW_HEIGHT // PIXELS_HEIGHT
        self.fill( INKY_BLACK )  # off

    def update( self ):
        pass

    def fill( self, colour ):
        self.image.fill( colour )



### MAIN
pygame.init()
pygame.font.init()
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
WINDOW  = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )
pygame.display.set_caption("Big-Pixel Sprite Test")


pixels = pygame.sprite.Group() 
for coords in [ ( 8,10 ), ( 18, 10 ), (6,15), (7,16), (8,17), (9,17), (10,17), (11,18), (12,18), (13,18), (14,18), (15,18), (16,17), (17,17), (18,17), (19,16), (20,15) ] :
    x,y = coords
    pixel = PixelSprite( x, y )
    pixel.fill( EGG_YELLOW )
    pixels.add( pixel )

clock = pygame.time.Clock()
done  = False
while not done:

    # Handle user-input
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            done = True
        elif ( event.type == pygame.KEYDOWN ):
            if ( event.unicode == 'q' or event.scancode == pygame.K_q ):
                done = True

    # Repaint the screen
    pixels.update()
    WINDOW.fill( INKY_BLACK )
    pixels.draw( WINDOW )

    pygame.display.flip()
    # Update the window, but not more than 60fps
    clock.tick_busy_loop( FPS )

pygame.quit()

pixel-sprite-output.png

...