7

我想在 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。请参阅 此页面。也许现在有一些更好的想法?

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

  • 应该如何从语言层面看动画?我相信,最好的方法是将每一帧视为一个页面。通过copypage增量更改可以轻松实现。可悲的是, 的语义copypage只存在于级别 1 和 2 中。在级别 3 中, 的含义copypage更改为showpage。多年前,我对 ghostscript 进行了一些修改,以将所有可见的更改延迟到copypageor showpage。这样,在服务器(即显示器)本地XCopyArea执行包含更改区域的单。

  • 应该如何同步视觉显示上的实际变化以避免在所描述的图形中不存在的伪影?您看到的不规则闪烁不是 PostScript 的特权,它似乎存在于我迄今为止看到的任何双缓冲系统中。只需尝试在您认为合适的任何系统中进行编程。

进一步编辑:

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

systemdict /.setlanguagelevel known {2 .setlanguagelevel} if

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

4

2 回答 2

4

我们在 comp.lang.postscript 上的这个线程中探讨了其中一些问题。

自 2 级标准发布以来,Postscript 是一种垃圾收集语言。您可以使用 fragment 禁用用户对象的收集-2 vmreclaim,但这并没有太大的作用。您可以通过调用该选项来禁用所有ghostscript 垃圾收集。-dNOGC这应该有助于防止图像的某些部分停止和吐出。

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 

whereflushpage 周围的守卫允许您将相同的代码发送给 ghostscript 以外的解释器(如打印机)。

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

于 2011-12-06T06:16:02.700 回答
3

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

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

这是一个使用“纯 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 的绘制方式。

于 2011-12-06T12:09:08.477 回答