Создаём Zoomquilt

в 11:42, , рубрики: python, автореферентность, анимация, Анимация и 3D графика, квайн, ненормальное программирование, метки: , ,

Захотелось продолжить серию постов о всяких интересных автореферентных штуковинах и решил я написать о жанре Zoomquilt. Сделал поиск, увидел, что один пост на Хабре уже есть. Подумал, подумал и решил, что пост я всё равно напишу, но он будет технический, о технологии создания Zoomquilt.

Для начала собственно о жанре. Тут проще показать чем рассказывать.

zoomquilt.org/

zoomquilt2.madmindworx.com/zoomquilt2.swf

www.syfy.com/tinman/oz/

www.deviantart.com/art/kopfsalat-digital-edition-30069104

Приближаемся к картинке и вместо того, чтобы в какой-то момент увидеть пиксели величиной с кулак, видим следующую картинку, повторяем процедуру многократно (на самом деле, выглядит это как один вполне себе плавный процесс и если художники хорошо поработали, то «стыков» мы вообще не увидим) и в итоге приходим к первоначальной картинке. В общем мультиквайны, только для художников.
А как такая штука делается? Конечно можно нарисовать это всё покадрово, более того, некоторые талантливые аниматоры вполне бы с этим справились. Но практически во всех существующих произведениях этого жанра указано, что это плоды коллективного творчества. Обычно есть коллектив художников, координатор проекта и программист, который собственно собирает это всё вместе и пишет интерфейс.

Дальше о технологии создания. Под катом много картинок.

Стал я искать информацию по технологии создания и мне повезло. Наткнулся на исходные изображения из которых состоял самый первый Zoomquilt. Вот одно из них:

Создаём Zoomquilt

Каждый «исходник» представляет собой изображение 1024*768 в середине которого находится чёрный прямоугольник размером 512*384.

Для начала разберёмся со сборкой zoomquilt из этих «исходников». Превратим картинки в полноценные кадры будущей анимации.
Понятно, что чёрный прямоугольник в центре изображения должен быть заменен следующим в списке изображением (для последнего изображения следующим является первое), уменьшенным до соответствующих размеров, причём перед тем, как заменять, нужно со следующим изображением проделать ту же процедуру и т.д. Пахнет это всё бесконечной рекурсией без условия останова, но к счастью, изображения дискретны и нарисовать что-либо размером меньше пикселя невозможно. Чёрный прямоугольник в центре картины будет уменьшаться, пока совсем не исчезнет и в этот момент замены можно прекратить.

Создаём Zoomquilt

Из полученных кадров конечно можно собрать анимацию

Создаём Zoomquilt

Но она будет прерывистой, т.к. в ней участвуют только ключевые кадры

Для каждого ключевого кадра можно создать при помощи приближения несколько промежуточных.

Создаём Zoomquilt

Окончательный вариант получился слишком тяжёлым для того, чтобы вставить его в статью, впрочем он мало отличается от оригинального ролика.

Это всё замечательно, собирать из готового мы уже умеем, но «исходники» кто-то должен нарисовать, причём так, чтобы все переходы были настолько плавными, чтобы не было понятно, где заканчивается одна картинка и начинается другая.
А происходит всё, насколько я понимаю, так:
Сначала координатор проекта даёт одному или нескольким художникам следующее изображение:

Создаём Zoomquilt

Художники должны заполнить всю зелёную зону и не должны трогать чёрную (точнее трогать они её могут, но всё, что они там нарисуют не будет учитываться при сборке). Затем, когда художники закончат работу, каждую из картин можно передать двум художникам. Один получает картину в таком виде:

Создаём Zoomquilt

Другой, в таком:

Создаём Zoomquilt

Обратите внимание, что размеры зелёных прямоугольников одинаковые на обеих картинах, ведь именно содержимое этого самого прямоугольника художник сдаёт координатору (ну или скорее координатор вырезает нужную часть из присланой картины).

Когда наберётся достаточное количество картин (минимум — 2, максимум не ограничен), координатор выдаст нескольким (вероятно самым сильным в проекте) художникам (их число равно числу художников, получивших в начале работы пустые картины) картины типа этой:

Создаём Zoomquilt

На этом круг замыкается, уроборос тихо переваривает хвост, а мы восторженно смотрим на очередное произведение.

Вот код, который я написал для этой статьи, писалось всё минут сорок на коленке, так что если кто-нибудь напишет по-человечески, с удовольствием и благодарностью вставлю сюда.

import PIL
from PIL import Image
from images2gif import writeGif

X,Y = 1024,768
IMAGES_NUM = 46

def render_images(raw_images):
    cur_index=0
    count = 0
    while True:
        count+=1
        if count == 100: break
        prev_index = cur_index - 1
        if prev_index == -1: prev_index = len(raw_images)-1
        cur_image = raw_images[cur_index]
        prev_image = raw_images[prev_index]        
        prev_image.paste(cur_image.resize((X/2,Y/2)),(X/4,Y/4))
        cur_index = prev_index
                  

def before_image(im):
    im1=Image.new("RGB",(X,Y),(0,255,0))
    im1.paste(im.resize((X/2,Y/2)),(X/4,Y/4))
    return im1

def after_image(im):
    im1 = im.copy()
    im1=im1.resize((X*2,Y*2))
    im1.paste(new_image(),(X/2,Y/2))
    return im1

def between_image(im1,im2):
    im = im1.copy()
    im=im.resize((X*2,Y*2))
    im.paste(before_image(im2),(X/2,Y/2))
    return im

def new_image():
    im1=Image.new("RGB",(X,Y),(0,255,0))
    im1.paste(Image.new("RGB",(X/2,Y/2),(0,0,0)),(X/4,Y/4))
    return im1

def between_frames(key_frame, number_of_frames):
    step_x = X/4/number_of_frames
    step_y = Y/4/number_of_frames
    l=[]
    for i in xrange(1,number_of_frames+1):
        x=step_x*i
        y=step_y*i
        l.append(key_frame.crop((x,y,x+(X-2*x),y+(Y-2*y))).resize((X,Y)))
    return l
                
def crop_image(im):
    im1=im.copy()
    x,y=im.size
    black=Image.new("RGB",(X/2,Y/2),(0,0,0)),(X/4,Y/4)
    if x==X:
        im1.paste(black)
    elif x==X*2:
        im1=im1.crop((X/2,Y/2,X/2+X,Y/2+Y))
        im1.paste(black)
    return im1    

Здесь есть все необходимые функции для создания своего Zoomquilt. Если что-то непонятно, спрашивайте.
Если есть желающие художники, пишите в личку, могу побыть координатором, сделаем хамбразумквилт :).

Если кто-нибудь знает ещё произведения в этом жанре, присылайте ссылки.

Спасибо за внимание.

Автор: gromozeka1980

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js