使用一个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)