当前位置: 首页 > 工具软件 > gif2apng > 使用案例 >

将GIF多张图片转成一张PNG图片,以便在游戏中可以方便使用

骆鸿运
2023-12-01

使用一个python库PIL完成。

可指定的参数为png图片最大宽度maxwidth,默认为4096。在这个限制下,如果一行放不下,就自动换行。

其他参数均作为要处理的gif文件名,将会进行遍历处理。gif文件名必须用.gif结尾,生成的文件将分别以.png和.lua结尾。

例如xx.gif会在同一个目录下生成xx.png和xx.lua文件。如果xx.png活xx.lua以及存在,则导致该文件被忽略,毕竟冒然覆盖文件可不好。

.lua文件中包含了.png文件的信息。如果需要生成其他格式的信息文件,请修改源码,增加一个将信息格式化输出的函数即可。

例如要处理gif_folder件夹下的所有gif文件,这么写:

./gif2png.py --maxwidth=4096 gif_folder/*.gif

py源码:

#!/usr/bin/python
from PIL import Image, ImageSequence
import sys 
import getopt
import re
import os

def gif2apng(input_filename, output_filename, maxwidth):
    # verify 
    gif = Image.open(input_filename)
    if gif.format != 'GIF':
        return False, 'the given file is not of gif format'

    # get information
    duration = gif.info['duration']
    h = gif.size[0]
    w = gif.size[1]
    if maxwidth < w:
        return False, 'maxwidth is less than single frame width'
    seq = 0 
    while True:
        try:
            seq += 1
            gif.seek(seq)
        except EOFError:
            break
    count = seq 
    width_all_frames = count * w 
    if maxwidth > width_all_frames:
        maxwidth = width_all_frames
    cnt_col = maxwidth / w # max 4096 pixels
    cnt_row = count / cnt_col
    if count > cnt_row * cnt_col:
        cnt_row += 1
    width = cnt_col * w 
    height = cnt_row * h 

    # do some conversion
    gif.info['background'] = gif.info['transparency']
    gif.convert('RGBA')

    # gif2png
    result = Image.new('RGBA', (width,height) )
    seq = 0 
    row = 0 
    col = 0 
    gif.seek(0)
    while True:
        try:
            tag,area,offset,extra = gif.tile[0]
            # crop the needed region
            region = gif.crop(area)
            box=(w*col+area[0],h*row+area[1])
            # paste the region to result
            result.paste(region, box)
            # goto the next frame
            seq = gif.tell() + 1 
            gif.seek(seq)
            col += 1
            if col == cnt_col:
                row += 1
                col = 0 
        except EOFError:
            break

    # finally, save the result
    result.save(output_filename, quality=100)
    return {"cell_width":w,'cell_height':h,'count':count,'duration':duration, 
        'cnt_row':cnt_row,'cnt_col':cnt_col,'width':width, 'height':height}, 'ok'
    
def info2lua(info, lua_filename):
    result = "return\n{\n"
    for info_name in info:
        result += "\t%s = %s,\n" % (info_name, info[info_name])
    result += "}\n"
    f = open(lua_filename, 'w') 
    f.write(result)
    f.close()

def get_shortname(path):
    r = re.compile("([a-zA-Z0-9_]*)\.gif$")
    m = r.search(path)
    if m:
        return m.group(1)

def check_exists(path):
    if os.path.exists(path):
        print(path + ": already exist")
        return False
    return path


# parse args
maxwidth = 4096
opts, gif_files = getopt.getopt(sys.argv[1:], "", ['maxwidth='])
for opt,value in opts:
    if opt == '--maxwidth':
        maxwidth = int(value)
    else:
        print('unknown parameter', opt, value)
        exit(-1)

# process gif files
for filename in gif_files:
    shortname = get_shortname(filename)
    if shortname:
        pngfile = check_exists(shortname + '.png')
        luafile = check_exists(shortname + '.lua')
        errmsg = 'cannot overwrite exist files'
        if pngfile and luafile:
            info, errmsg = gif2apng(filename, pngfile, maxwidth)
            if info:
                # add your functions here to export info to more format :)
                info2lua( info, luafile )
                print(filename + ": ok")
                continue
    else:
        errmsg = 'specify a .gif file please'
    print(filename + " FAILED: %s" % errmsg)



 类似资料: