流畅的 PostScript 动画
我想在 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 进行了一些修改来延迟所有可见更改最多可达copypage
或showpage
。通过这种方式,包含更改区域的单个XCopyArea
在服务器(即显示器)上本地执行。应该如何同步视觉显示上的实际变化以避免所描述的图形中不存在的伪影?您看到的不规则闪烁并不是 PostScript 的特权,它似乎存在于我迄今为止见过的任何双缓冲系统中。只要尝试在您认为合适的任何系统中对此进行编程即可。
进一步编辑:
要获得正确的语言级别,即级别 1 或 2(对于 Ghostscript):
systemdict /.setlanguagelevel known {2 .setlanguagelevel} if
编辑:我添加此评论可能会吸引一些新的 postscript 贡献者。
I would like to run animations in PostScript smoothly. To see what I want, let me switch to PostScript directly. Call ghostscript, and
200 dup scale .5 setgray 0 0 3 3 rectfill
We have now a gray square.
0 setgray 0 1 3 1 rectfill
With a black stripe in it. We will now fill that stripe, one time white
and black in succession:
{1 setgray 0 1 3 1 rectfill 0 setgray 0 1 3 1 rectfill} loop
You will see now some flickering of black and white rectangles that
are smaller than the original black stripe. Ideally, we would see
the original grey square. Or almost. Where can I get such functionality today?
To see a more interesting animation sequence searching for magic
squares of size 5:
wget http://www.complang.tuwien.ac.at/ulrich/gupu/l5.eps.gz
zcat l5.eps.gz | ghostscript -
A couple of years ago I did try to address these issues. But it never went into ghostscript or Xfree. See
this page. Maybe there are some better ideas now?
Edit: After reading the responses so far, let me clarify one issue here. Essentially, there are two independent issues in this question:
How should an animation be viewed from the language level? I believe, the best way is to view each frame as a single page. With
copypage
incremental changes can be realized with low effort. Sadly, that semantics ofcopypage
is only present in Level 1 and 2. In Level 3, the meaning ofcopypage
changed toshowpage
. I did - many years ago - a little modification to ghostscript to delay all visible changes up tocopypage
orshowpage
. In this manner, a singleXCopyArea
containing the changed area is performed locally on the server (that is, the display).How should actual changes on the visual display be synchronized to avoid artefacts that where not present in the graphics described? The irregular flicker you see is not a privilege of PostScript, it seems to be present in any double-buffered system I have seen so far. Just try to program this in whatever system you see fit.
Further edit:
To get the right language level, that is level 1 or 2 do (for ghostscript):
systemdict /.setlanguagelevel known {2 .setlanguagelevel} if
Edit: I am adding this comment to may attract some new postscript contributors.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我们在 comp.lang 上的这个帖子中探讨了其中一些问题。后记。
自 Level 2 标准发布以来,Postscript 就是一种垃圾收集语言。您可以使用片段
-2 vmreclaim
禁用用户对象的收集,但它并没有多大作用。您可以通过使用-dNOGC
选项调用来禁用所有 Ghostscript 垃圾收集。这应该有助于防止图像部分停顿和吐出。Ghostscript 有一个名为 flushpage 的非标准运算符,它可以将渲染与执行。这有助于确保所有内容在消失之前都被看到。
而对于时序控制,似乎没有比简单的忙等待更好的方法了。
围绕flushpage 的
where
保护允许您将相同的代码发送到ghostscript 以外的解释器(如打印机)。如果您有实际的 Display Postscript 服务器,则可以使用
wait
运算符而不是忙等待。We explored some of these issues in this thread on comp.lang.postscript.
Since the release of the Level 2 standard, Postscript is a garbage-collected language. You can disable collection of user objects with the fragment
-2 vmreclaim
, but it doesn't accomplish much. You can disable ALL ghostscript garbage collection by invoking with the-dNOGC
option. This should help prevent stalling and spitting with parts of the image.Ghostscript has a non-standard operator called flushpage, which synchronizes the rendering with the execution. This helps make sure that everything is seen before it's gone.
And for timing control, there doesn't seem to be a better way than simple busy-waiting.
The
where
guards around flushpage allow you to send the same code to interpreters other than ghostscript (like a printer).If you had an actual Display Postscript server, you could use the
wait
operator instead of busy-waiting.虽然我喜欢(并赞成)@luserdroog 的答案,但我不认为 Postscript 应该以这种方式用于动画 - 我宁愿使用某种可以运行小部件或显示专为实时显示和用户交互而设计的元素的语言- 这不是后记或鬼记的情况。
不过,我认为使用 postscript 来达到渲染目的会很好 - 只需在每次修改图像后渲染一个页面,并使用外部程序将不同的页面组装为动画帧。
甚至可能使用 postscript 作为渲染引擎,用另一种语言调用 Ghostscript 来实时渲染每个帧。一个很好且易于使用的多媒体框架可以做到这一点,例如带有 Pygame 模块的 Python 语言。
这是一个使用“纯 python + pygame”的简短示例。
要执行此操作,您必须拥有 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的绘制方式。
Although I like (and upvoted) @luserdroog's answer, I don't believe Postscript should be used for animations on this way - I'd rather use some language that can run widgets or display elements that are designed for real time display and user interation - that is not the case of postscript or ghostscript.
I think it would be nice, though, use postscript for aimations for rendering purposes - just rendering a page after each modification on the image, and using an external program to assemble the different pages as animation frames.
Maybe even using postscript as a rendering engine, with the process in another language calling ghostscript to render each frame in realtime. A nice and easy to use multimedia framework to do that could be for example, the Python language with the Pygame module.
Here is a short example using "pure python + pygame".
To execute this, you have to have Python and Pygame (from http://pygame.org - there are ready packages on most linux systems for that)
Pygame's drawing API is much poorer than postscript - if you need more than rectangles
(like bezies, scaling, rotating and shearing the coordinate system, and so on), the way to go is to use Cairo + python + some display library (which might be pygame, GTK+ or qt) . Cairo is a 2D drawing library that inherits from the postscript way. - or, as I said above, to drive a ghostscript external process using Python, having it generating a rle compressed image file to stdout or a ramdrive, and that image read and displayed frame by frame using python + pygame.
Another option is to use HTML5's Canvas, and do everything in Javascript, viewable on a browser. HTML5's Canvas also inherits the Postscript way of drawing.