Как получить правильные размеры для прямоугольника pygame, созданного на основе изображения

#python #pygame

Вопрос:

Я создал прямоугольник изображения спрайта с помощью команды, pygame.image.get_rect() . При определении координат ключевых точек на прямоугольнике, например, bottomleft путем рисования точек, я вижу, что размеры прямоугольника полностью отличаются от размеров изображения. В этом случае изображение-это просто головка стрелки. Правая верхняя координата прямоугольника правильна, однако левая нижняя координата неправильна.

Проверьте, чтобы увидеть прямоугольник

код для рисования точек:

 pygame.draw.circle(simulation_screen, red, velocity_arrow.rect.topright, 2)
pygame.draw.circle(simulation_screen,red,velocity_arrow.rect.bottomleft,2)
 

Как я могу изменить размер прямоугольника, чтобы он соответствовал изображению?

Комментарии:

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

Ответ №1:

pygame.Surface.get_rect.get_rect() возвращает прямоугольник с размером объекта поверхности. Эта функция не учитывает область рисования на изображении. Если вы хотите найти ограничивающий прямоугольник окрашенной области на поверхности, вам нужно создать маску.

pygame.mask.from_surface создает pygame.mask.Mask форму объекта a pygame.Surface .
Поверхность является растровым изображением. Маска представляет собой 2-мерный массив с логическими значениями. Созданная маска соответствует размеру _поверхности. Поле — это True если соответствующий пиксель на поверхности непрозрачен, и False если он прозрачен:

 surf_mask = pygame.mask.from_surface(surf)
 

Получите список, содержащий ограничивающие прямоугольники (последовательность pygame.Rect объектов) для каждого подключенного компонента с. get_bounding_rects
pygame.mask.Mask.get_bounding_rects создает список pygame.Rect объектов. Каждый прямоугольник описывает ограничивающую область соединенных пикселей. Если поверхность содержит ровно 1 связное изображение, вы получите ровно 1 прямоугольник, окружающий изображение:

 rect_list = surf_mask.get_bounding_rects()
 

Создайте объединенный прямоугольник последовательности прямоугольников с unionall :

 surf_mask_rect = rect_list[0].unionall(rect_list)
 

См. Пример. Черный прямоугольник — это прямоугольник поверхности, а красный прямоугольник — объединение прямоугольников компонентов маски:

repl.it/@Rabbid76/ImageHitbox

 import pygame

def getMaskRect(surf, top = 0, left = 0):
    surf_mask = pygame.mask.from_surface(surf)
    rect_list = surf_mask.get_bounding_rects()
    surf_mask_rect = rect_list[0].unionall(rect_list)
    surf_mask_rect.move_ip(top, left)
    return surf_mask_rect

pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

try:
    my_image = pygame.image.load('Bomb-256.png')
except:
    my_image = pygame.Surface((200, 200), pygame.SRCALPHA)
    pygame.draw.circle(my_image, (0, 128, 0), (60, 60), 40)
    pygame.draw.circle(my_image, (0, 0, 128), (100, 150), 40)

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    pos = window.get_rect().center
    my_image_rect = my_image.get_rect(center = pos)
    my_image_mask_rect = getMaskRect(my_image, *my_image_rect.topleft)

    window.fill((255, 255, 255))
    window.blit(my_image, my_image_rect)
    pygame.draw.rect(window, (0, 0, 0), my_image_rect, 3)
    pygame.draw.rect(window, (255, 0, 0), my_image_mask_rect, 3)
    pygame.display.flip()

pygame.quit()
exit()