-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTestGif.py
More file actions
216 lines (196 loc) · 6.9 KB
/
TestGif.py
File metadata and controls
216 lines (196 loc) · 6.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#coding=utf-8
'''用自
http://blog.csdn.net/yangalbert/article/details/7603338
'''
from PIL import Image
from PIL.GifImagePlugin import getheader, getdata
import zipfile
import os
import shutil
def intToBin(i):
""" 把整型数转换为双字节 """
# 先分成两部分,高8位和低8位
i1 = i % 256
i2 = int( i/256)
# 合成小端对齐的字符串
return chr(i1) + chr(i2)
def getheaderAnim(im):
""" 生成动画文件头 """
bb = "GIF89a"
bb += intToBin(im.size[0])
bb += intToBin(im.size[1])
bb += "\x87\x00\x00" #使用全局颜色表
return bb
def getAppExt(loops=0):
""" 应用扩展,默认为0,为0是表示动画是永不停止
"""
bb = "\x21\xFF\x0B" # application extension
bb += "NETSCAPE2.0"
bb += "\x03\x01"
if loops == 0:
loops = 2**16-1
bb += intToBin(loops)
bb += '\x00' # end
return bb
def getGraphicsControlExt(duration=0.1):
""" 设置动画时间间隔 """
bb = '\x21\xF9\x04'
bb += '\x08' # no transparancy
bb += intToBin( int(duration*100) ) # in 100th of seconds
bb += '\x00' # no transparant color
bb += '\x00' # end
return bb
def _writeGifToFile(fp, images, durations, loops):
""" 把一系列图像转换为字节并存入文件流中
"""
# 初始化
frames = 0
previous = None
for im in images:
if not previous:
# 第一个图像
# 获取相关数据
palette = getheader(im)[1] #取第一个图像的调色板
data = getdata(im)
imdes, data = data[0], data[1:]
header = getheaderAnim(im)
appext = getAppExt(loops)
graphext = getGraphicsControlExt(durations[0])
# 写入全局头
fp.write(header)
fp.write(palette)
fp.write(appext)
# 写入图像
fp.write(graphext)
fp.write(imdes)
for d in data:
fp.write(d)
else:
# 获取相关数据
data = getdata(im)
imdes, data = data[0], data[1:]
graphext = getGraphicsControlExt(durations[frames])
# 写入图像
fp.write(graphext)
fp.write(imdes)
for d in data:
fp.write(d)
# 准备下一个回合
previous = im.copy()
frames = frames + 1
fp.write(";") # 写入完成
return frames
def writeGif(filename, images, duration=0.1, loops=0, dither=1):
""" writeGif(filename, images, duration=0.1, loops=0, dither=1)
从输入的图像序列中创建GIF动画
images 是一个PIL Image [] 或者 Numpy Array
"""
images2 = []
# 先把图像转换为PIL格式
for im in images:
if isinstance(im,Image.Image): #如果是PIL Image
images2.append( im.convert('P',dither=dither) )
elif np and isinstance(im, np.ndarray): #如果是Numpy格式
if im.dtype == np.uint8:
pass
elif im.dtype in [np.float32, np.float64]:
im = (im*255).astype(np.uint8)
else:
im = im.astype(np.uint8)
# 转换
if len(im.shape)==3 and im.shape[2]==3:
im = Image.fromarray(im,'RGB').convert('P',dither=dither)
elif len(im.shape)==2:
im = Image.fromarray(im,'L').convert('P',dither=dither)
else:
raise ValueError("图像格式不正确")
images2.append(im)
else:
raise ValueError("未知图像格式")
# 检查动画播放时间
durations = [duration for im in images2]
# 打开文件
fp = open(filename, 'wb')
# 写入GIF
try:
n = _writeGifToFile(fp, images2, durations, loops)
finally:
fp.close()
return n
############################################################
## 将多帧位图合成为一幅gif图像
def images2gif( images, giffile, durations=0.05, loops = 1):
seq = []
for i in range(len(images)):
im = Image.open(images[i])
background = Image.new('RGB', im.size, (255,255,255))
background.paste(im, (0,0))
seq.append(background)
frames = writeGif( giffile, seq, durations, loops)
print frames, 'images has been merged to', giffile
## 将gif图像每一帧拆成独立的位图
def gif2images( filename, distDir = '.', type = 'bmp' ):
if not os.path.exists(distDir):
os.mkdir(distDir)
print 'spliting', filename,
im = Image.open( filename )
im.seek(0) # skip to the second frame
cnt = 0
type = string.lower(type)
mode = 'RGB' # image modea
if type == 'bmp' or type == 'png':
mode = 'P' # image mode
im.convert(mode).save(distDir+'/%d.'%cnt+type )
cnt = cnt+1
try:
while 1:
im.seek(im.tell()+1)
im.convert(mode).save(distDir+'/%d.'%cnt+type)
cnt = cnt+1
except EOFError:
pass # end of sequence
white = (255,255,255)
preIm = Image.open(distDir+'/%d.'%0+type).convert('RGB')
size = preIm.size
prePixs = preIm.load()
for k in range (1,cnt):
print '.',
im = Image.open(distDir+'/%d.'%k+type).convert('RGB')
pixs = im.load()
for i in range(size[0]):
for j in range(size[1]):
if pixs[i,j] == white:
pixs[i,j] = prePixs[i,j]
preIm = im
prePixs = preIm.load()
im.convert(mode).save(distDir+'/%d.'%k+type)
print '\n', filename, 'has been splited to directory: [',distDir,']'
return cnt # 总帧数
##############################################################
if __name__ == '__main__':
#解压文件(成功)
os.mkdir('id=59844679')
images = []
filename = 'id=59844679.zip'
fz = zipfile.ZipFile(filename,'r')
for file in fz.namelist():
print (file)
images.append(file)
fz.extract(file,'id=59844679'+'/')
#frames = gif2images('source.gif',distDir='tmp',type='png')
#images = []
#for i in range(frames-1,-1,-1):
# images.append('tmp/%d.png'%i)
os.chdir('id=59844679')
images2gif(images,'save.gif', durations = 0.05)
if os.path.exists(os.path.abspath('..')+'\\'+'save.gif'):
os.chdir(os.path.abspath('..'))
os.remove('save.gif')
os.chdir('id=59844679')
#将gif移动到上级目录
shutil.move('save.gif',os.path.abspath('..'))
else:
shutil.move('save.gif',os.path.abspath('..'))
print os.path.abspath('..')
os.chdir(os.path.abspath('..'))
shutil.rmtree('id=59844679')