Измените размер содержимого изображения, но сохраните размеры изображения

#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(). Это даст вам поверхность, которая действительно похожа на виртуальную поверхность, которая предоставляет окно в подраздел исходной поверхности. Он ссылается на те же пиксели, что и исходная поверхность, поэтому, если один из них изменен, он виден и в другом. Однако это не кажется проблемой для того, что вы делаете.