我已经创建了一个非常天真的页面,它将采用一个3.js场景(尽管这可能是任何非WebGL<canvas>
动画),并导出单个图像(或图像序列)然后转换为视频。
我这样做部分是为了学习Python,但是能够在Three.js中快速创建一些原型,然后导出一个巨大的高分辨率平滑视频的想法对我来说非常有吸引力。在过去,我用屏幕捕捉软件捕捉视频,虽然它总是觉得有点笨重和实时下降的FPS将显示通过在最后的视频。
我目前的流程如下:
Javascript代码:
创建WebGL场景并设置渲染周期
将画布宽度/高度设置为所需的尺寸
使用requestAnimationFrame
渲染场景
暂停场景的渲染/更新周期
在canvas元素上调用toDataURL()
并检索base64字符串
向python脚本发送请求,传递base64字符串(以及其他内容,例如要保存到的目标目录,以及是否捕获单个图像或序列)
蟒蛇:
删除MIME头内容类型并解码base64字符串
将字符串写入图像文件
如果文件已写入,则打印/返回一个表示成功状态的字符串,否则打印出有问题的错误消息
导入base64、cgi、cgib、datetime、glob、re、oscgitb.enable()#cgitb.enable(display=0, logdir='/tmp')print "Content-type: text/html"printdef main(): form = cgi.FieldStorage() saveLocation = "../httpdocs/export/" # POST variables dataURL = form['dataURL'].value captureSequence = form['captureSequence'].value folderName = saveLocation + form['folderName'].value saveImage(dataURL, captureSequence, saveLocation, folderName)def saveImage(dataURL, captureSequence, saveLocation, folderName): # strip out MIME content-type (e.g. "data:image/png;base64,") dataURL = dataURL[dataURL.index(','):] decodedString = base64.decodestring(dataURL) if captureSequence == 'true': # based off http://www.akeric.com/blog/?p=632 currentImages = glob.glob(folderName + "/*.jpg") # TODO: perhaps filenames shouldnt start at %08d+1 but rather %08d+0? numList = [0] if not os.path.exists(folderName): os.makedirs(folderName) for img in currentImages: i = os.path.splitext(img)[0] try: num = re.findall('[0-9]+$', i)[0] numList.append(int(num)) except IndexError: pass numList = sorted(numList) newNum = numList[-1] + 1 saveName = folderName + '/%08d.jpg' % newNum else: if not os.path.exists(saveLocation): os.makedirs(saveLocation) saveName = saveLocation + datetime.datetime.now().isoformat().replace(':', '.') + '.jpg' # TODO; rather than returning a simple string, consider returning an object? try: output = open(saveName, 'w') output.write(decodedString) output.close() print 'true' except Exception, e: print eif __name__ == '__main__': main()
Javascript代码:
从Python脚本接收响应并显示返回消息
恢复/更新渲染周期
(根据需要对多个帧重复此过程)
这是一个我总是在本地运行的东西,这样就不会有写冲突或类似的风险。
我做了一些快速的测试,如果有点慢的话,在大部分情况下都是有效的。
我是不是错过了一些很明显的事情?如何改进?(尤其是在python方面)
对每个图像执行单独的ajax调用是否效率低下?一个优点是,我可以随时停止/关闭选项卡,它将保存所有图像直到那时。存储所有这些base64字符串并在最后发送它们有什么好处吗?
由于requestAnimationFrame
将更新周期限制为60fps,是否可以轻松设置较低的帧速率?假设出于某种风格上的原因,我想以每秒15帧的速度更新所有内容,那么唯一的选择是使用setTimeout(callback, 1000 / targetFPS)
并理解它将drift over time?
从上面开始,这个动画有一个varframe
值,它在每个更新周期中递增1
。然后,该变量用于控制动画的不同部分(例如,旋转立方体,并传递到顶点/片段着色器以操纵颜色和纹理UV坐标)。
如果我想模拟像15 fps这样的东西,我需要将frame
增加(60 / 15)
是否正确?有没有一种更优雅的方法可以轻松地在有上限的帧速率之间切换?
最后,有没有什么技术可以用来提高被渲染图像的质量?(大声思考,存两倍的钱然后减少?)
我真的希望这是有意义的,任何洞察或建议都会得到极大的赞赏。
源文件:http://cl.ly/3V46120C2d3B0A1o3o25(在Mac/Chrome稳定版上测试,需要WebGL)
最佳答案
在EaselJS中,您可以设置FPS
EaselJS Ticker
关于javascript - 将HTML Canvas 导出为图像序列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8900498/