Photostory is a tool to generate slideshows using Blender. It can generate videos directly, but also offers more customization using the following workflow: GUI ➜ JSON ➜ Blender ➜ render. Videos below.

… continued:

There is a bunch of people – including myself – that is keen about photography, as well as open-source software. The two are not always coming along greatly, as companies behind professional software for digital photographers usually neglect our niche audience. Linux is scarcely supported and Wine / VM workarounds are not entirely optimal. Luckily, though, there is significant effort by the community to improve the landscape of professional-level tools. Anyhow, in this post I don’t want to write about photography tools in general, but about something more specific: How to show selected pictures to family and friends?

After taking countless pictures during a back-packing tour, I recently wanted to generate a slideshow to present some of the captured moments to my family. Ideally, such a slideshow is a plain video file which can be played universally, for instance on the TV of my parents. In the Mac world, I guess, you could use iPhoto for this task but I was disappointed with the alternatives offered for Windows or Linux. Even professional tools, such as Lightroom, provide a rather cumbersome workflow and in the end I decided to write a small tool that allows you to easily arrange photos and create a video. The rendering part is handled by Blender, which also allows you to customize the generated scene. The features I wanted to have are the following:

  • GUI: A graphical user-interface to drag-and-drop photographs
  • Multi-picture slides: Each slide can have an arbitrary amount of pictures
  • Auto-layout: The layout is generated automatically (but can be customized)
  • Background pictures: Ability to set foreground and background pictures for each slide
  • Routes: Support of GPS-slides, which animate a route given a set of GPS coordinates
  • Extensibility: An extensible tool-chain that allows to add different effects and designs

My first idea was to write a single C++ application with a front-end to do the arrangement of photographs and a back-end for the rendering, using image libraries such as opencv or imagemagick. After some considerations, however, I realised that some 3D effects like ambient occlusion and the animation of routes would involve more development than I was willing to invest and making such a tool extensible would lead to a fair amount of planning and overhead on its own. Instead, I opted for a scriptable animation software to do the rendering and my clear choice was to opt for Blender. Ultimately, the front-end is a Qt C++ application, which exports the arrangement of slides to a JSON file. This file is then loaded by a blender-plugin that automatically generates geometry, textures and camera movement. The user interface is able to completely hide the execution of Blender, but also allows you to get your hands dirty and tweak or augment the scene if you wish to do so.

Automatic workflow

The automatic workflow hides details of the manual process away, but obviously gives you fewer settings to adjust. The following video shows how to arrange slides using the photo-selector:

And here is the result after rendering:

Manual workflow

Instead of rendering the video directly from the GUI it is possible to save the JSON exchange format in order to import it into Blender manually. The resulting file describes slides like this:

    "type": "photo_slide",
    "name": "3",
    "background_paths": [],
    "foreground_paths": [

In Blender load the slideshow via File ➜ Import ➜ Photostory (.json). This importer gives you the options:

  • Unroll map: If set, adds an unrolling map animation to the beginning of the scene (see example).
  • Skip duplicates: If set, placeholder images for duplicate frames are created in the output directory (this directory needs to be specified in Blender before importing). This will speed up the rendering process significantly as long as the overwrite flag in Blender is not set. After rendering, placeholders need to be replaced using the script </br> photo-selector/, which replaces empty image files with the previous non-empty image.
  • Setup scene: If set, scene properties such as start and end frame are adjusted as well.
  • Default slide duration: Default duration of slides (might be overwritten by JSON).


Now you have the opportunity to customize the slideshow in 3D using Blender. The generated scene should work with the internal as well as Cycles renderer. Rendering is done usual, only make sure not to change the output directory if you generated placeholders with be setting skip duplicates.

Features I like

  • The Blender addon sets up materials compatible with Cycles and the internal renderer of Blender
  • The map uses a height-map and (optionally) shows an unrolling animation when it’s shown for the first time
  • Videos are supported as well. If a slide contains a video, it is shown long enough for the video to finish
  • The addon tries to reduce rendering time by skipping identical frames


  • The workflow is one-directional. Adjustments that were done manually in Blender stay in Blender. Of course, the modified Blender scene can be saved and used as always, but if you re-order slides in the GUI you have to import a new JSON file which generates a new Blender scene. Hence, modifications you did in Blender with an old iteration of you slideshow will not be applied to the new version. As a consequence, think of Blender as an optional tool for post-production that is used after finalizing the JSON slideshow.
  • Even if identical frames are skipped and the internal renderer is used, rendering can easily take hours. (Hopefully this will improve with EEVEE, which is not supported yet)


Photostory is hosted on github and you are more than welcome to contribute. Please open issues if you find bugs or have recommendations and ideally, create pull requests if you can fix issues yourself. Maybe you also have good ideas for generating layouts or scenes with different styles.