Krita Scripting: Export Top Level Layers into PNGs

Exporting layers into individual image files is something you may have to do quite often when working in Krita.

Manually exporting a couple of layers is rather easy. Things get complicated, and time consuming, when you need to make frequent changes, or when you have a large number of layers.

In this tutorial, we will write a Python script that exports your top level layers into PNG files.

Our Goal

Let’s say we have a .kra file with three lovely car sprites, each in its own layer.

Our file has 3 layers: car 1, car 2 and car 3, plus the Background layer

We want Krita to create PNG files each named after the corresponding layer.

How we want the exported files to look like

We also want our script to:

  • Organize the files in a folder next to our .kra file
  • Have the size of each PNG file match the size of the layer
  • Ignore specific layers like the Background layer

Let’s Code!

Open Scripter by going to Tools > Scripts > Scripter.

The Scripter interface

Let’s start by importing the krita and os modules.

Let’s also get a reference to the active document.

from krita import *
import os

doc = Krita.instance().activeDocument()

The Export Directory

We will store the PNG files in a subfolder named export_png located next to our .kra file.

The path to our export directory is obtained by:

  1. Using os.path.dirname with the document’s file path as argument to get the path to our working directory.
  2. Using os.path.join to add export_png to our working directory’s path.

If the export directory doesn’t exist in the filesystem (which is to be expected when you run the script for the first time), we’ll create it using os.makedirs.

wdir = os.path.dirname(doc.fileName())
exportDir = os.path.join(wdir, "export_png")

if not os.path.isdir(exportDir):
  os.makedirs(exportDir)

Looping Through Top Level Layers

Before doing anything, we need Krita to go into Batch Mode, because we don’t want annoying dialogs to popup every time we run our script.

Application.setBatchmode(True)

(Application is just a shortcut for Krita.instance().)

In Python, layers are called nodes.

To get the list of top level nodes, we use Document.topLevelNodes(), and we loop through them with a for loop.

for node in doc.topLevelNodes():

Let’s avoid exporting any layer named background or references. We’ll use continue to skip the current iteration.

  if node.name().lower() in ["background", "references"]:
    continue

If you’re wondering why I’ve used lowercase names, it’s because I want the comparison to be case-insensitive.

Exporting Nodes to PNG files

First, let’s get the path to our PNG file. This is easy since we already have the path to our export directory.

  path = os.path.join(exportDir, node.name() + ".png")

Saving a node to PNG (or any format for that matter) is easy. The Node class has a convenient save method that we can use.

The save method requires an InfoObject as argument, which needs specific properties for each file format. These properties are what Krita asks you about in a popup dialog when you manually export through the graphical user interface.

If you’re not in Batch Mode, you’re gonna see a ton of these, yay for Batch Mode!
  info = InfoObject()
  info.setProperty("alpha", True)
  info.setProperty("compression", 9)
  info.setProperty("forceSRGB", False)
  info.setProperty("indexed", False)
  info.setProperty("interlaced", False)
  info.setProperty("saveSRGBProfile", False)
  info.setProperty("transparencyFillcolor", [0,0,0])

  node.save(path, doc.resolution(), doc.resolution(), info)

You probably don’t need to set every property of the InfoObject. Some of them have default values. But I like to be thorough and have complete control over my script.

That’s it for our loop!

Let’s wrap things up by going out of Batch mode and displaying a nice little message.

Application.setBatchmode(False)
QMessageBox.information(Application.activeWindow().qwindow(), "Done and Done", "All done!")

Okay, we’re done, phew!

Press the play button in the Scripter interface to run your script.

Full Script

from krita import *
import os

doc = Krita.instance().activeDocument()
wdir = os.path.dirname(doc.fileName())

exportDir = os.path.join(wdir, "export_png")

if not os.path.isdir(exportDir):
  os.makedirs(exportDir)

Application.setBatchmode(True)

for node in doc.topLevelNodes():

  if node.name().lower() in ["background", "references"]:
    continue

  info = InfoObject()
  info.setProperty("alpha", True)
  info.setProperty("compression", 9)
  info.setProperty("forceSRGB", False)
  info.setProperty("indexed", False)
  info.setProperty("interlaced", False)
  info.setProperty("saveSRGBProfile", False)
  info.setProperty("transparencyFillcolor", [0,0,0])

  path = os.path.join(exportDir, node.name() + ".png")

  node.save(path, doc.resolution(), doc.resolution(), info)

Application.setBatchmode(False)
QMessageBox.information(Application.activeWindow().qwindow(), "Done and Done", "All done!")

Challenges

You can take your script to the next level, here are a few challenges for you :

  • Turn your script into a Krita extension that adds a menu item to Krita’s graphical user interface.
  • Have PNG files match the size of the document rather than the node’s.
  • Export all layers in all open documents, rather than just in the active document like we did in this tutorial.

Krita’s class reference and scripting school are your friends.

Happy coding!