Smooth PostScript animation

I want to run animation in PostScript smoothly. To see what I want, let me switch directly to PostScript. Call ghostscript and

200 dup scale .5 setgray 0 0 3 3 rectfill 

Now we have a gray square.

 0 setgray 0 1 3 1 rectfill 

With a black stripe in it. Now we will fill this strip, once white and black in a row:

 {1 setgray 0 1 3 1 rectfill 0 setgray 0 1 3 1 rectfill} loop 

You will now see the flickering black and white rectangles that are smaller than the original black bar. Ideally, we would see the original gray square. Or almost. Where can I get this functionality today?

To see a more interesting sequence of animation in search of magic squares of size 5:

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

A few years ago I tried to solve these problems. But it never got into ghostscript or Xfree. See this page . Maybe there are some better ideas right now?

Edit: After reading the answers so far, let me clarify one question here. In fact, there are two independent problems in this matter:

  • How should I view animation from a language level? I think the best way is to view each frame as one page. With copypage incremental changes can be implemented with minimal effort. Unfortunately, this copypage semantics copypage present only in Levels 1 and 2. At level 3, the value of copypage has changed to showpage . I made - many years ago - a small modification of ghostscript to defer all visible changes to copypage or showpage . Thus, a single XCopyArea containing the changed region runs locally on the server (i.e., on the display).

  • How should the actual changes be synchronized on the visual display to avoid artifacts that are not present in the chart? The incorrect flickering you see is not a PostScript privilege; it seems to be present on any two-buffer system I have seen so far. Just try to program this on any system that suits you.

Further editing:

To get the correct language level, i.e. level 1 or 2 (for ghostscript):

 systemdict /.setlanguagelevel known {2 .setlanguagelevel} if 

Edit: I am adding this comment to attract some new .

+6
source share
2 answers

We examined some of these issues in this thread at comp.lang.postscript .

Starting with the release of the Level 2 standard, Postscript has been a garbage collected language. You can disable the collection of custom objects using the -2 vmreclaim fragment, but this is not enough. You can disable the entire ghostscript garbage collection by calling the -dNOGC . This should help prevent tearing and spitting with parts of the image.

Ghostscript has a non-standard operator called flushpage , which synchronizes rendering with execution. This helps ensure that everything is seen before it disappears.

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

And to manage time, there seems to be no better way than just waiting.

 /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 

The where protections around the flushpage allow you to send the same code to other interpreters other than ghostscript (like a printer).

If you had the actual Postscriptcript server, you can use the wait statement instead of busy waiting.

+4
source

Although I like (and above) @ luserdroog's answer, I don’t think Postscript should be used for animations in this way - I would rather use some kind of language in which you can run widgets or display elements designed for real-time display and custom tampering - this does not apply to postscript or ghostscript.

I think it would be nice to use a postscript for rendering purposes - just render the page after each modification in the image and use an external program to build different pages as animated frames. It is even possible to use postscript as a rendering engine, with a process in another language calling ghostscript to render each frame in real time. A good and easy-to-use multimedia infrastructure for this can be, for example, the Python language with the Pygame module.

Here is a brief example using "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() 

To accomplish this, you must have Python and Pygame (from http://pygame.org - there are ready-made packages for most Linux systems for this)

Pygame's drawing API is much worse than postscript - if you need more rectangles (e.g. meringues, scaling, rotating and shifting the coordinate system, etc.), the way to use is to use Cairo + python + some display library (which could be pygame , GTK + or qt). Cairo is a 2D drawing library that inherits from the postscript path. - or, as I said above, manage the external ghostscript process using Python by creating its rle compressed image file in stdout or ramdrive, and this image is read and displayed frame by frame using python + pygame.

Another option is to use an HTML5 canvas and do everything in Javascript visible in the browser. HTML5 Canvas also inherits the way Postscript is drawn.

+3
source

Source: https://habr.com/ru/post/903153/


All Articles