平滑PostScript动画
我想在PostScript中顺利运行动画。要查看我想要什么,让我直接切换到PostScript。调用ghostscript,然后平滑PostScript动画,postscript,animation,x11,ghostscript,double-buffering,Postscript,Animation,X11,Ghostscript,Double Buffering,我想在PostScript中顺利运行动画。要查看我想要什么,让我直接切换到PostScript。调用ghostscript,然后 200 dup scale .5 setgray 0 0 3 3 rectfill 我们现在有一个灰色的正方形 0 setgray 0 1 3 1 rectfill 上面有一条黑色的条纹。我们现在将填充条纹,一次为白色 接着是黑人: {1 setgray 0 1 3 1 rectfill 0 setgray 0 1 3 1 rectfill} loop 现在您将
200 dup scale .5 setgray 0 0 3 3 rectfill
我们现在有一个灰色的正方形
0 setgray 0 1 3 1 rectfill
上面有一条黑色的条纹。我们现在将填充条纹,一次为白色
接着是黑人:
{1 setgray 0 1 3 1 rectfill 0 setgray 0 1 3 1 rectfill} loop
现在您将看到一些闪烁的黑白矩形
比原来的黑色条纹小。理想情况下,我们会看到
原来的灰色正方形。或者差不多。我今天在哪里可以获得这样的功能
要查看更有趣的动画序列,请搜索magic
大小为5的正方形:
wget http://www.complang.tuwien.ac.at/ulrich/gupu/l5.eps.gz
zcat l5.eps.gz | ghostscript -
几年前,我确实试图解决这些问题。但它从未进入ghostscript或Xfree。看见
. 也许现在有更好的主意
编辑:在阅读了到目前为止的回复之后,让我在这里澄清一个问题。基本上,这个问题有两个独立的问题:
- 如何从语言级别查看动画?我认为,最好的方法是将每个框架视为单个页面。使用
可以轻松实现增量更改。遗憾的是,copypage
的语义只存在于第1级和第2级。在级别3中,copypage
的含义更改为copypage
。许多年前,我曾尝试将所有可见更改延迟到showpage
或copypage
。以这种方式,在服务器(即显示器)上本地执行包含更改区域的单个showpage
XCopyArea
- 如何同步视觉显示上的实际变化,以避免所述图形中不存在的人工制品?您看到的不规则闪烁不是PostScript的特权,它似乎出现在我迄今为止看到的任何双缓冲系统中。只要试着在你认为合适的任何系统中编程就行了
编辑:我将此评论添加到可能吸引一些新撰稿人的文章中。我们在中探讨了其中一些问题 自从2级标准发布以来,Postscript是一种垃圾收集语言。您可以使用片段
-2 vmreclail
禁用用户对象的收集,但这并不能实现多少功能。通过使用-dNOGC
选项调用,可以禁用所有ghostscript垃圾回收。这将有助于防止图像的某些部分出现停滞和吐痰
Ghostscript有一个名为的非标准操作符,它将渲染与执行同步。这有助于确保所有东西都在消失之前被看到
对于时间控制,似乎没有比简单的忙碌等待更好的方法了
/smallpause {
/flushpage where{pop flushpage}if
50 sleep } def
/pagepause {
/flushpage where{pop flushpage}if
1000 sleep } def
/sleep {
usertime add {
10 {
1 100000 div pop %busy
.1 sin 257 cos atan pop %busy busy
} repeat
dup usertime le {exit}if
} loop pop
} def
冲洗页面周围的where
防护装置允许您将相同的代码发送给除ghostscript(如打印机)以外的口译员
如果你有一个真正的Display Postscript服务器,你可以使用等待
操作符,而不是忙着等待。尽管我喜欢(并投了赞成票)@luserdroog的答案,我不认为Postscript应该以这种方式用于动画——我宁愿使用一些可以运行小部件或显示元素的语言,这些小部件或显示元素是为实时显示和用户交互而设计的——而不是Postscript或ghostscript
/smallpause {
/flushpage where{pop flushpage}if
50 sleep } def
/pagepause {
/flushpage where{pop flushpage}if
1000 sleep } def
/sleep {
usertime add {
10 {
1 100000 div pop %busy
.1 sin 257 cos atan pop %busy busy
} repeat
dup usertime le {exit}if
} loop pop
} def
不过,我认为最好使用postscript进行目标渲染——只需在每次修改图像后渲染一个页面,并使用外部程序将不同的页面组装为动画帧。
甚至可以使用postscript作为渲染引擎,使用另一种语言调用ghostscript的过程实时渲染每个帧。例如,一个好用且易于使用的多媒体框架可以是带有Pygame模块的Python语言
下面是一个使用“纯python+pygame”的简短示例
要执行此操作,必须有Python和Pygame(从-在大多数linux系统上都有现成的软件包)
Pygame的绘图API比postscript差得多——如果您需要的不仅仅是矩形的话
(如bezies、缩放、旋转和剪切坐标系等),方法是使用Cairo+python+一些显示库(可能是pygame、GTK+或qt)。Cairo是一个从postscript方式继承的二维图形库。-或者,如上所述,使用Python驱动ghostscript外部进程,让它生成一个rle压缩图像文件到stdout或ramdrive,并使用Python+pygame逐帧读取和显示该图像
另一个选择是使用HTML5的画布,用Javascript做任何事情,可以在浏览器上查看。HTML5的画布也继承了Postscript的绘图方式。这里有两个问题。应该看到什么?如何与显示器进行交互?你对前者感兴趣,我对后者更感兴趣。我认为冲洗法不是一个好办法
copypage
(也就是说,只有1级和2级语义)是干净的、合乎逻辑的方式。这是有道理的。我还没有从copypage
获得我想要的结果。它总是执行我不想要的擦除页面。我可能需要升级我的ghostscript安装。不!您必须将语言级别设置为1或2。我在文档中找不到它!如何设置语言级别?我把它放在问题的末尾:它过去是:systemdict/.setlanguagelevel已知{2.setlanguagelevel}如果
我从1990年左右开始使用PostScript制作动画。到目前为止,我还没有看到任何其他编程语言能够实现相同的2D功能。顺便说一句,你有没有尝试过在另一个框架中编写原始程序?我很想看看,是否有任何系统能够准确显示这样的图形。只是想澄清一下:画一个3x3大小的灰色正方形,画一条3x1大小的矩形条纹,改变
/smallpause {
/flushpage where{pop flushpage}if
50 sleep } def
/pagepause {
/flushpage where{pop flushpage}if
1000 sleep } def
/sleep {
usertime add {
10 {
1 100000 div pop %busy
.1 sin 257 cos atan pop %busy busy
} repeat
dup usertime le {exit}if
} loop pop
} def
#! /usr/bin/env python
# coding: utf-8
import pygame
size = 640,480 #(in pixels)
# multiplying factor so that the whole image is 5 units across
factor = size[0] / 5.0
# Inits pygame drawing window
screen = pygame.display.set_mode(size)
# Rectangle drawing function that scales drawing using the factor above
def draw_rect(color, rect):
new_rect = [int (r * factor) for r in rect]
return pygame.draw.rect(screen, color, new_rect)
def main():
draw_rect((128,128,128), (0, 0, 3, 3))
colors = ((255,255,255), (0,0,0))
color_index = 0
while True:
draw_rect(colors[color_index], (0, 1, 3, 1))
pygame.display.flip()
color_index = 1 - color_index
pygame.time.delay(50) # in miliseconds
try:
main()
finally:
pygame.quit()