#python #image #pygame
#python #изображение #pygame
Вопрос:
Я пытаюсь создать базовую копию Pokemon на Python с помощью PyGame. В прошлом я следовал нескольким руководствам, касающимся этой библиотеки. Итак, для этого проекта у меня будет базовая структура плитки, либо трава, либо вода. Игроку не разрешается переходить на плитку с водой, но он может свободно перемещаться по плитке с травой. Спрайт, который я получил с помощью руководства, имеет размеры 64 x 64 и занимает все пространство плитки, поэтому вокруг границ нет прозрачных пикселей.
Однако для моих целей мне нужно использовать мои собственные спрайты (64 x 64), которые я получил из таблицы спрайтов. Однако в этом случае верхняя половина изображения отображается в виде прозрачных неиспользуемых пикселей. То же самое относится к четвертям с каждой стороны спрайта. Итак, мне нужно пакетно изменить размер всех этих спрайтов, умножив размер видимого пикселя на 2 по обеим осям. Т. Е. Просто увеличьте размер спрайта с коэффициентом масштабирования 2. Я мог бы легко это сделать, но это все равно было бы неэффективно, поскольку новый размер спрайта будет 128 x 128, а соотношение неиспользуемых пикселей останется прежним.
Мой вопрос:
- Как я могу изменить размер спрайтов с коэффициентом масштабирования 2 и при этом сохранить исходные размеры 64 x 64, просто удалив прозрачные пиксели, которые будут находиться за пределами рамки 64 x 64?
Мне нужен метод, который я мог бы использовать для всех имеющихся у меня 9600 спрайтов, предпочтительно на Python, хотя я бы не возражал против решения с помощью какого-либо другого программного обеспечения.
Я пытался искать решения в Интернете, но я не знаю, как правильно сформулировать этот вопрос.
Ответ №1:
Создайте пустой pygame.Surface
объект с прозрачной буквой и размером 32×32:
new_image = pygame.Surface((32, 32), pygame.SRCALPHA)
blit
желаемая область (32, 16, 32, 32) формирует исходный спрайт 64×64 ( original_image
) на новой поверхности:
new_image.blit(original_image, (0, 0), (32, 16, 32, 32))
Масштабируйте новый объект Surface на pygame.transform.smoothscale
new_image = pygame.transform.smoothscale(new_image, (64, 64))
Комментарии:
1. Я получаю <Поверхность (32x32x32 SW)> как new_image после «blit». Однако в следующей строке я получаю сообщение об ошибке: ‘pygame. Объект Surface’ не имеет атрибута ‘pygame’. Кроме того, original_image должен быть surface, верно, иначе я получаю ошибку типа «pygame. Поверхность, а не str» в части «blit». Первая ошибка, вероятно, как-то связана с моим ужасающим пониманием ООП.
2. @user12937488 Извините, я виноват. В ответе была ошибка. Я исправил это.
new_image.pygame.transform.smoothscale(new_image, (64, 64))
должно бытьnew_image = pygame.transform.smoothscale(new_image, (64, 64))
Ответ №2:
Если это изображения, вы можете легко сделать это с помощью PIL.
from PIL import Image
Игнорируйте этот бит, который просто создает тестовое изображение 64×64
from scipy import misc
img = misc.face()
img=Image.fromarray(np.uint8(img))
img=img.resize((64,64))
Здесь должен быть изображен милый маленький енот
Затем мы можем изменить размер в два раза, как вы описываете (ПРИМЕЧАНИЕ: я не использую тот факт, что это квадратное изображение, просто чтобы это было более обобщенным. Вы могли бы немного упростить это с imsz=img.size[0]
)
imsz=img.size
# resize by factor of 2
img=img.resize((imsz[0]*2,imsz[1]*2))
Что должно дать изображение в 2 раза большего размера
Теперь мы просто обрезаем его
# box – The crop rectangle, as a (left, upper, right, lower)-tuple
crpimg=img.crop(box=(int(0.5*imsz[0]),int(0.5*imsz[1]),int(1.5*imsz[0]),int(1.5*imsz[1])))
Что дает нам изображение размером 64×64:
Комментарии:
1. Это отличный ответ и решение. Но я думаю, что спрашивающий попросил решение с pygame .
2. Да, это еще одно очень хорошее решение. Я обязательно попробую это вместе с принятым решением, на случай, если в будущем у меня возникнут какие-либо другие проблемы, которых этот метод мог бы избежать. Спасибо!
Ответ №3:
Ответ @ Rabbid76 о копировании / размытии раздела оригинала, а затем его увеличении / масштабировании — хороший вариант и, вероятно, именно так я бы и поступил.
Однако, если вы уже изменили их размер до большего размера и просто хотите обрезанную версию существующего изображения / поверхности, вы можете использовать subsurface(). Это даст вам поверхность, которая действительно похожа на виртуальную поверхность, которая предоставляет окно в подраздел исходной поверхности. Он ссылается на те же пиксели, что и исходная поверхность, поэтому, если один из них изменен, он виден и в другом. Однако это не кажется проблемой для того, что вы делаете.