Модуль pygame.image. Использование изображений

Функция load() модуля pygame.image загружает изображение и создает экземпляр Surface, на котором отображено это изображение. В load() передается имя файла. "Родным" форматом является BMP, однако если функция pygame.image.get_extended() возвращает истину, то можно загружать ряд других форматов: PNG, GIF, JPG и др.

import pygame as pg
import sys

W = 400
H = 300

sc = pg.display.set_mode((W, H))
sc.fill((100, 150, 200))

dog_surf = pg.image.load('dog.bmp')
dog_rect = dog_surf.get_rect(bottomright=(W, H))
sc.blit(dog_surf, dog_rect)

pg.display.update()

while 1:
    for i in pg.event.get():
        if i.type == pg.QUIT:
            sys.exit()

    pg.time.delay(20)
Загрузка BMP-изображения

Если у изображения нет прозрачного слоя, но он необходим, то следует воспользоваться методом set_colorkey() класса Surface:

dog_surf = pg.image.load('dog.bmp')
dog_surf.set_colorkey((255, 255, 255))

Все пиксели, цвет которых совпадает с переданным в set_colorkey() значением, станут прозрачными.

set_colorkey

У формата PNG с альфа-каналом (когда для точек можно настраивать степень прозрачности; обычно устанавливается полностью прозрачный фон) таких проблем нет:

sun_surf = pg.image.load('sun.png')
sun_rect = sun_surf.get_rect()
sc.blit(sun_surf, sun_rect)
Изображение с альфа-каналом

Ко всем экземплярам Surface рекомендуется применять метод convert(), который, если не передавать аргументы, переводит формат кодирования пикселей поверхности в формат кодирования пикселей главной поверхности. При выполнении игры это ускоряет отрисовку поверхностей.

Если поверхность была создана на базе изображения с альфа-каналом, то вместо convert() надо использовать метод convert_alpha(), так как первый удаляет прозрачные пиксели (вместо них будет черный цвет). Таким образом, код загрузки и обработки изображений разных форматов должен выглядеть примерно так:

dog_surf = pg.image.load('dog.bmp').convert()

sun_surf = pg.image.load('sun.png').convert_alpha()

Что по смыслу равносильно:

...
dog_surf = pg.image.load('dog.bmp')
dog_surf = dog_surf.convert()
...

Метод convert() возвращает новую, конвертированную, поверхность. Он не изменяет ту, к которой применяется.

Так как изображение загружается в программу в виде экземпляра Surface, связанную с ним переменную можно передавать в метод blit(), таким образом создавая анимацию. В примере фоновую поверхность мы создаем с помощью явного вызова класса Surface. Также можно было бы использовать изображение в качестве фона, а не только движущегося объекта.

import pygame as pg
import sys

W = 800
H = 300

sc = pg.display.set_mode((W, H))
bg = pg.Surface((W, H))
bg.fill((100, 150, 200))
sc.blit(bg, (0, 0))

sun = pg.image.load('sun.png').convert_alpha()
sun_rect = sun.get_rect(topleft=(0, 20))
sc.blit(sun, sun_rect)

pg.display.update()

while 1:
    for i in pg.event.get():
        if i.type == pg.QUIT:
            sys.exit()

    sc.blit(bg, sun_rect, sun_rect)
    sun_rect.x += 1
    sc.blit(sun, sun_rect)
    pg.display.update()

    pg.time.delay(20)

В модуле pygame.image есть функция save(), которая позволяет сохранять переданную ей поверхность (не обязательно главную) в формат BMP, TGA, PNG, JPEG. Пример:

while 1:
    for i in pygame.event.get():
        if i.type == pygame.QUIT:
            sys.exit()
        elif i.type == pygame.KEYUP and i.key == pygame.K_s:
            pygame.image.save(sc, 'day.png')

    pygame.time.delay(20)

Практическая работа

Измените пример с анимацией из урока таким образом, чтобы в качестве фона использовалась картинка, а размер главного окна подстраивался под ее размеры, которые можно получить с помощью метода поверхностей get_size(). Также запрограммируйте управление движущимся объектом влево и вправо с помощью стрелок клавиатуры (сам по себе он перемещаться не должен).