平滑的PostScript动画

时间:2011-12-05 23:55:13

标签: animation x11 ghostscript postscript 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

现在你会看到一些闪烁的黑白矩形 小于原始的黑色条纹。理想情况下,我们会看到 原来的灰色方块。或差不多。我今天在哪里可以获得这样的功能?

要查看更有趣的动画序列搜索魔法 大小为5的正方形:

wget http://www.complang.tuwien.ac.at/ulrich/gupu/l5.eps.gz
zcat l5.eps.gz | ghostscript -

几年前,我确实试图解决这些问题。但它从未进入过ghostscript或Xfree。看到 this page。也许现在有一些更好的想法?

编辑:到目前为止阅读回复后,让我在这里澄清一个问题。从本质上讲,这个问题有两个独立的问题:

  • 如何从语言级别查看动画?我相信,最好的方法是将每个帧视为一个页面。通过copypage可以轻松实现增量更改。遗憾的是,copypage的语义仅出现在1级和2级。在3级中,copypage的含义变为showpage。多年前我做了little modification to ghostscript,将所有可见的更改延迟到copypageshowpage。通过这种方式,在服务器(即显示器)上执行包含更改区域的单个XCopyArea 本地

  • 如何同步视觉显示上的实际变化以避免所描述的图形中不存在的人工制品?您看到的不规则闪烁不是PostScript的特权,它似乎存在于我迄今为止看到的任何双缓冲系统中。试着用你认为合适的系统编程。

进一步编辑:

要获得正确的语言级别,即1级或2级(对于ghostscript):

systemdict /.setlanguagelevel known {2 .setlanguagelevel} if

编辑:我添加此评论可能会吸引一些新的贡献者。

2 个答案:

答案 0 :(得分:4)

我们在this thread on comp.lang.postscript中探讨了其中一些问题。

自Level 2标准发布以来,Postscript是一种垃圾收集语言。您可以使用片段-2 vmreclaim禁用用户对象的集合,但这并不能完成。您可以通过使用-dNOGC选项调用来禁用 ALL ghostscript垃圾回收。这应有助于防止图像部分停滞和随地吐痰。

Ghostscript有一个名为flushpage的非标准运算符,它将渲染与执行同步。这有助于确保在它消失之前一切都看到

- flushpage -
On displays, flushes any buffered output, so that it is guaranteed to
show up on the screen; on printers, has no effect

对于时间控制,似乎没有比简单忙碌等待更好的方法。


/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 

围绕flushpage的where防护允许您将相同的代码发送给ghostscript以外的解释器(如打印机)。

如果你有一个实际的Display Postscript服务器,你可以使用wait运算符而不是忙等待。

答案 1 :(得分:3)

虽然我喜欢(并且赞成)@ luserdroog的答案,我不相信Postscript应该用于这种方式的动画 - 我宁愿使用一些可以运行小部件的语言或显示为实时显示而设计的元素和用户交互 - 这不是postscript或ghostscript的情况。

我认为这很好,但是,使用postscript动画用于渲染 - 只需在图像上的每次修改后渲染页面,并使用外部程序将不同的页面组合为动画帧。 甚至可能使用postscript作为渲染引擎,使用另一种语言的进程调用ghostscript来实时渲染每个帧。一个好的和易于使用的多媒体框架可以做,例如,使用Pygame模块的Python语言。

这是一个使用“pure python + pygame”的简短示例。

#! /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()

要执行此操作,您必须拥有Python和Pygame(来自http://pygame.org - 大多数Linux系统上都有现成的软件包)

Pygame的绘图API比postscript更差 - 如果你需要的不仅仅是矩形 (如bezies,缩放,旋转和剪切坐标系等),要走的路是使用Cairo + python +一些显示库(可能是pygame,GTK +或qt)。 Cairo是一个继承自postscript方式的2D绘图库。 - 或者,如上所述,使用Python驱动ghostscript外部进程,让它生成一个rle压缩图像文件到stdout或ramdrive,并使用python + pygame逐帧读取和显示该图像。

另一个选择是使用HTML5的Canvas,并在Javascript中执行所有操作,可在浏览器中查看。 HTML5的Canvas也继承了Postscript的绘图方式。