Плавная анимация 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.

2 ответа

Мы рассмотрели некоторые из этих проблем в этой теме на comp.lang.postscript.

После выпуска стандарта уровня 2 Postscript является языком для сбора мусора. Вы можете отключить коллекцию пользовательских объектов с фрагментом -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 

where Охранники вокруг flushpage позволяют отправлять один и тот же код другим интерпретаторам, кроме ghostscript (например, на принтер).

Если у вас был настоящий сервер Display Postscript, вы могли бы использовать wait оператор вместо занятого ожидания.

Хотя мне нравится (и одобряется) ответ @luserdroog, я не верю, что Postscript следует использовать для анимации таким образом - я бы предпочел использовать некоторый язык, который может запускать виджеты или элементы отображения, предназначенные для отображения в реальном времени и взаимодействия с пользователем. - это не случай постскриптума или ghostscript.

Я думаю, что было бы неплохо, однако, использовать PostScript для анимации в целях визуализации - просто отображать страницу после каждой модификации изображения и использовать внешнюю программу для сборки различных страниц в качестве кадров анимации. Возможно даже использование postscript в качестве движка рендеринга, когда процесс на другом языке вызывает ghostscript для рендеринга каждого кадра в реальном времени. Хорошим и простым в использовании мультимедийным фреймворком для этого может быть, например, язык Python с модулем Pygame.

Вот краткий пример использования "чистого 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)

API рисования в Pygame намного беднее, чем postscript - если вам нужно больше, чем прямоугольники (например, бези, масштабирование, вращение и сдвиг системы координат и т. Д.), Можно использовать Cairo + python + некоторую библиотеку отображения (которая может быть pygame, GTK+ или qt) . Cairo - это библиотека 2D-чертежей, которая наследуется от PostScript. - или, как я уже говорил выше, для управления внешним процессом ghostscript с использованием Python, который генерирует сжатый файл образа rle для stdout или ramdrive, и это изображение читается и отображается кадр за кадром с помощью python + pygame.

Другой вариант - использовать HTML5 Canvas и делать все в Javascript, который можно просматривать в браузере. Canvas в HTML5 также наследует способ создания PostScript.

Другие вопросы по тегам