我正在使用 Python 创建一个程序,该程序可以使用 Sprite 存储库中的 Sprite 表自动为我制作 Pokemon gif。它结合了动画和它的阴影来创建一个 sprite 表,然后将其切割成帧。这些帧被组装成 GIF,然后在程序中显示在画布内,所以我知道要下载什么。 GIF 在 cavasses 中的外观和功能非常完美,但是当我使用 PIL 并尝试保存 GIF 时,它会做一些奇怪的事情,它会裁剪框架,因此框架的边缘和阴影有时会被移除,就像它不必要地夹在框架周围一样.
正如您在下面的代码中看到的,我尝试了几乎所有我知道的方法。不过,我很可能会遗漏一些东西。
请注意,每个帧在保存之前都是完全相同的大小,即使调整它们的大小,问题仍然存在。当每个帧单独导出时,它会保留其原始大小,只有当它试图将所有帧一起放入 gif 时才会出现问题。
def download_this(button, download_single_buttons):
export_directory = config.get('Directory', 'export_directory')
idx = download_single_buttons.index(button)
starting_frame_index = idx * num_cols
canvas_frames = frames[starting_frame_index: starting_frame_index + num_cols]
canvas_frames = [ImageTk.getimage(f) for f in canvas_frames]
durations = frame_duration_values[:num_cols]
loop_value = 0 if loop_check_value.get() else 1
if loop_value == 0:
filename = f"{export_directory}\{(this_poke.lower())}-{(animations.lower())}({directions[idx]}).gif"
else:
filename = f"{export_directory}\{(this_poke.lower())}-{(animations.lower())}_once({directions[idx]}).gif"
canvas_frames[0].save(filename, format="GIF", append_images=canvas_frames[1:], save_all=True, loop=loop_value,
transparency=0, disposal=[2] * len(canvas_frames), duration=durations,
compress_level=0, save_local_palette=True, width=frame_width, height=frame_height)
我也会附上创建框架的方法:
def generate_gifs(anim_selected, animations, search_poke_number, this_poke):
global photo_img, frames
url = f'https://github.com/PMDCollab/SpriteCollab/blob/master/sprite/{int(search_poke_number[0]) + 1:04}/AnimData.xml?raw=true'
response = requests.get(url)
root = ET.fromstring(response.content)
for anim in root.findall('./Anims/Anim'):
if anim.find('Name').text == animations:
frame_width = int(anim.find('FrameWidth').text)
frame_height = int(anim.find('FrameHeight').text)
frame_duration_values = [int(dur.text) * 20 for dur in anim.findall('./Durations/Duration')]
shadow_size = root.find('ShadowSize').text
anim_url = f'https://github.com/PMDCollab/SpriteCollab/blob/master/sprite/{int(search_poke_number[0]) + 1:04}/{animations}-Anim.png?raw=true'
shadow_url = f'https://github.com/PMDCollab/SpriteCollab/blob/master/sprite/{int(search_poke_number[0]) + 1:04}/{animations}-Shadow.png?raw=true'
response = requests.get(anim_url)
anim_img = Image.open(io.BytesIO(response.content))
response = requests.get(shadow_url)
shadow_img = Image.open(io.BytesIO(response.content))
shadow_arr = np.array(shadow_img)
white = [255, 255, 255, 255]
blue = [0, 0, 255, 255]
green = [0, 255, 0, 255]
red = [255, 0, 0, 255]
black = [0, 0, 0, 255]
transparent = [0, 0, 0, 0]
colour_list = [white, green, red, blue]
# Replace the colors with black or transparent based on shadow_size
i = 0
while i <= 3:
if i <= int(shadow_size) + 1:
shadow_arr[(shadow_arr == colour_list[i]).all(axis=2)] = black
else:
shadow_arr[(shadow_arr == colour_list[i]).all(axis=2)] = transparent
i += 1
shadow_img = Image.fromarray(shadow_arr)
# Combine the images and merge them with the shadow image underneath
merged_img = Image.alpha_composite(shadow_img, anim_img)
photo_img = ImageTk.PhotoImage(merged_img)
# Calculate the number of columns and rows in the sprite sheet
num_cols = photo_img.width() // frame_width
num_rows = photo_img.height() // frame_height
# Create a list of PhotoImage objects for each frame in the GIF
frames = [None] * (num_rows * num_cols)
frame_count = 0
for row in range(num_rows):
for col in range(num_cols):
x1 = col * frame_width
y1 = row * frame_height
编辑:所以在尝试了几天之后,它似乎与保存功能本身有关。即使我确保文件大小正确,当我尝试将它们一起保存为 gif 时,它们也会发生变化。即使将单个帧保存到文件夹并从中组装 gif 也会导致完全相同的问题。在这一点上,我只是在寻找替代方案/解决方法。
自上次编辑以来,我没有发现问题,也没有得到任何帮助。如果甚至有一个人对如何解决这个问题有一点点想法,那么我将不胜感激。