Exporting animated gifs

Animated gifs are old and inefficient, but in some places it’s the only format you can upload.

It’s easy to use the ffmpeg video writer from OPENRNDR to produce such files. Here a template:

Imports
import org.openrndr.application
import org.openrndr.draw.isolatedWithTarget
import org.openrndr.draw.renderTarget
import org.openrndr.ffmpeg.VideoWriter
import org.openrndr.ffmpeg.VideoWriterProfile
import java.lang.Math.toDegrees
import kotlin.math.PI
fun main() = application {
    configure {
        width = 512
        height = 512
    }
    program {
        val videoWriter = VideoWriter.create().apply {
            size(width, height)
            profile(GIFProfile())
            output("/tmp/my_anim.gif")
            start()
        }

        val videoTarget = renderTarget(width, height) {
            colorBuffer()
            depthBuffer()
        }

        val totalFrames = 120

        extend {
            val norm = (frameCount % totalFrames) / totalFrames.toDouble() // cycles 0.0 .. 1.0
            val radians = 2 * PI * norm // cycles 0.0 .. TWO_PI
            val angle = toDegrees(radians) // cycles 0.0 .. 360.0
            drawer.isolatedWithTarget(videoTarget) {
                // Draw stuff here.
                // You can use one of the three variables above
                // to produce looping animations.
            }

            videoWriter.frame(videoTarget.colorBuffer(0))
            drawer.image(videoTarget.colorBuffer(0))

            if (frameCount == totalFrames) {
                videoWriter.stop()
                application.exit()
            }
        }
    }

}

class GIFProfile : VideoWriterProfile() {
    override fun arguments(): Array<String> {
        return arrayOf("-vf", "split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse=dither=none:diff_mode=rectangle")
    }
}

The simple GIFProfile optimizes the colors and disables the dithering. With dithering I was getting very heavy files. Once the file is exported, I run this command to optimize the file further:

gifsicle --loop --delay=2 --colors 16 --optimize=2 my_anim.gif >my_anim_optimized.gif

Delay 2 gives about 60 fps I think. I try to reduce the colors as much as possible, depending on what I’m drawing. You can read more about gifsicle.

Do you have any tricks to make gif loops?

1 Like

This is going to be a bit easier in the next version. The functionality can be previewed by updating build.gradle.kts: upgrade to OPENRNDR 0.3.44-rc.1 and ORX 0.3.53-rc.1 and add "orx-video-profiles" to the list of extensions.

demo:

2 Likes