如何截取屏幕并生成GIF动画
来源:互联网 发布:新疆大学教育网络系统 编辑:程序博客网 时间:2024/06/06 02:51
前面在写关于VPython的文章的时候,我考虑了一下如何把VPython的动作记录下来,存为GIF动画再放到博客上来.
首先,在维基百科找到关于GIF文件格式的描述, 由于该部分占用篇幅太多,我就不贴出来了,大家可以查看这里:
http://en.wikipedia.org/wiki/Graphics_Interchange_Format
有了上面的信息,就可以编写Python程序了,PIL里面有个类ImageGrab可以轻易地截取屏幕.另外,python的写文件时,可以直接写入字符串和十六进制数,非常方便.以下是整个程序源代码:
# -*- coding: cp936 -*-import ImageGrab # from PILimport timeimport stringfrom PIL import Image, ImageChopsfrom PIL.GifImagePlugin import getheader, getdataimport osimport numpy as npdef 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 bbdef 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 bbdef 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 bbdef _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 framesdef 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) print n, '帧图像已经写入' finally: fp.close()seq = []steps = float(raw_input("输入录制间隔(单位:秒):"))x = raw_input("按下任意键开始录制...")os.system("mkdir images") #创建一个文件夹,用于存放临时文件for i in range(10): time.sleep(steps) im = ImageGrab.grab((0,0,320,245)) #捕捉屏幕的左上角(0,0,320,245)部分 #这里由于ImageGrab.grab返回的图像格式未知,只能使用笨办法,每次存盘再打开,格式就正确了 im.save("images\\test" +str(i) + ".gif") #图像存入 seq.append(Image.open("images\\test" +str(i) + ".gif")) #重新打开 print "采集了第" + str(i) + "帧图像"print "屏幕捕捉完成"writeGif('output.gif',seq, duration=0.5, dither=0)x = raw_input("按下任意键退出")使用方法:
1,运行程序,弹出"输入录制间隔(单位:秒):", 输入你希望的间隔,比如0.5秒.
2,按下任意键开始录制
3,捕捉完成后,按下任意键结束.
4,最终的GIF文件将保存为当前目录下的output.gif
程序输出:
输入录制间隔(单位:秒):0.1
按下任意键开始录制...
采集了第0帧图像
采集了第1帧图像
采集了第2帧图像
采集了第3帧图像
采集了第4帧图像
采集了第5帧图像
采集了第6帧图像
采集了第7帧图像
采集了第8帧图像
采集了第9帧图像
屏幕捕捉完成
10 帧图像已经写入
按下任意键退出
最终效果:
- 如何截取屏幕并生成GIF动画
- 如何截取屏幕并生成GIF动画
- 截取屏幕生成GIF
- iOS怎样截取屏幕并生成图片?
- iOS怎样截取屏幕并生成图片?
- vc gif 动画生成
- gif动画生成工具
- C++截取整个屏幕,并生成图片(基于MFC)
- 【WP 8.1开发】如何动态生成Gif动画项目
- 如何进行屏幕截取
- 如何截取屏幕图片
- 用JAVA生成GIF动画
- 用JAVA生成GIF动画
- 用JAVA生成GIF动画
- Matlab 动画及Gif生成
- FFmpeg截取视频生成高清Gif
- Android如何播放gif动画
- Android录制屏幕并转为GIF
- JSP的运行原理
- xml
- jQuery对所有name为一个值或约等于一个值的标签统一赋值
- Linux之设备驱动学习简过程<一>
- 动态网页和静态网页的比较
- 如何截取屏幕并生成GIF动画
- 子衿的事(52)
- 学生课堂感受_郭冰
- u盘被写保护
- 未来互联网领域投资方向
- 【欣赏】一组伤感唯美的图片
- Android执行linux外部命令
- 成员函数重载运算符和友元函数重载运算符的比较
- 藏汇于民只是一张空头支票