TSA

The Strange Agency

Diffusion Collusion

By using a mask with the Stability API, we can create prompt-generated collages of arbitrary length. We can also subtly change the prompt being used throughout the collage.

Stitching

We need to start by creating a masking image that will be sent to the API along with a source image. The API will keep the part of our image where the mask is white, and it will fill in the black area. This was made in Photopea, an awesome alternative to Adobe.

After every generation, we want to keep the top 256 pixels of the returned image, and use the remaining 512 (i.e. 768 - 256) pixels for our next API call.

# set up transformation matrix
a, b, d, e = 1, 0, 0, 1
c = 0  # left / right
f = 256  # up / down

if artifact.type == generation.ARTIFACT_IMAGE:
    result = Image.open(io.BytesIO(artifact.binary))
    output.append(result)
    # now translate output for next round
    source = result.transform(result.size, Image.AFFINE, (a, b, c, d, e, f))

When we have generated all of our images, we stitch them together into a collage.

output_count = len(output)
collage = Image.new('RGB', (768, 256 + output_count * 256))

for i in range(1, output_count):
  collage.paste(im=output[i], box=(0, (i-1) * 256))

Scrolling

Finally, we can use ffmpeg to generate a scrolling animation of our collage. We calculate the height of our collage based on the length of the output array created in the main loop (though we could also query the height of the collage image created above). We set an arbitrary length of 32 seconds for the scroll and calculate a rate accordingly. Finally, we concoct a heinously complex ffmpeg command to get the party moving.

Note that we have an rm scroll.mp4 command in there, to clean up after a previous run. This will keep the ffmpeg from asking if you should erase the previously generated video. You may or may not want this feature. Also we use unsetopt nomatch to keep some shells from complaining about the [video] part of the command.

height = (1 + output_count) * 256
height = height - 432
rate = height / 32

! rm scroll.mp4
! unsetopt nomatch; ffmpeg -r 1 -loop 1 -t 33 -i collage.png -filter_complex "color=white:s=768x432, fps=fps=30[bg];[bg][0]overlay=y=-{height}+'t*{rate}':shortest=1[video]" -preset ultrafast -map [video] scroll.mp4

See the full source here. Now got out and scroll!