Krita

Un modèle pilote Krita 5.2.9 par le Hub pour peindre une carte postale sur deux calques et l’enregistrer dans un fichier .kra. Le premier script a fonctionné. Cette page donne le texte, le script, les réponses du Hub et la capture, et dit comment le pont a été démarré : pas depuis Scripter, qui n’a pas été essayé.

Des mots en plusieurs langues défilent sur un paysage peint dans Krita ; le mouvement est rendu par le Hub dans Blender.

Démarrer Krita avec son pont

Le guide fait lancer le fichier du pont par l’opérateur depuis Scripter. Cette exécution n’a pas utilisé ce geste. Elle a démarré Krita sur un serveur X virtuel, dans un profil neuf, avec une extension de démarrage dont tout le __init__.py exécute le fichier du pont :

xvfb-run -a krita --nosplash
exec(open('/usr/share/libremodular-mcp/bridges/krita_bridge.py', encoding='utf-8').read())

L’encodage n’est pas facultatif. Le Python embarqué de Krita lit les fichiers dans l’encodage de la locale sous laquelle il a été lancé, et le fichier du pont contient des caractères accentués : sous la locale C, une commande sans encoding='utf-8' s’est arrêtée avec UnicodeDecodeError, comme le consigne la page de compatibilité. L’exécution a utilisé le port 9312 dans config.toml et un jeton neuf. Le port s’est mis à l’écoute 10,4 s après le démarrage, et get_state sur hub a listé Krita comme connecté :

Réponse du Hub
{
  "app": "hub",
  "app_version": "0.1.0",
  "bridge_version": null,
  "captured_at": "2026-10-21T12:47:48.951Z",
  "connected": true,
  "content_origin": "hub",
  "screenshot": null,
  "state": {
    "modules": [
      {
        "app_version": "5.2.9",
        "bridge_version": "1",
        "connected": true,
        "mode": "tcp",
        "name": "krita"
      }
    ]
  },
  "warnings": []
}

Texte donné au modèle

Texte donné au modèle
In Krita, create a document named “Postcard”, 600 by 400 pixels. On a paint layer named “Sky”, paint a vertical gradient from dark blue (#1c385c) at the top to teal (#29a196) at the bottom. On a second paint layer named “Hill”, paint a copper (#c25438) hill: the upper half of an ellipse centred on the bottom edge, 520 pixels wide and 240 pixels high. Save the document as postcard.kra in your working directory.

Avant d’écrire, le modèle a appelé get_state sur krita : "document": null. Le document n’existe pas encore, de sorte que le script doit le créer et l’ouvrir dans une fenêtre avant de pouvoir peindre.

Script écrit

Un modèle, Claude Sonnet 5.5, a écrit ce script à partir du guide et de cet état. Ce n’est pas un script tiré des tests du projet. Le script écrit les octets des pixels dans l’ordre bleu, vert, rouge, alpha ; les couleurs de la capture ci-dessous montrent que c’est l’ordre que Krita attend pour ce document. Le script active le mode batch avant saveAs ; ce qui se passe sans lui n’a pas été essayé.

python · Script écrit
import os

krita = Krita.instance()
document = krita.createDocument(600, 400, "Postcard", "RGBA", "U8", "", 72.0)
krita.activeWindow().addView(document)
root = document.rootNode()

def lerp(a, b, t):
    return round(a + (b - a) * t)

top, bottom = (0x1c, 0x38, 0x5c), (0x29, 0xa1, 0x96)
sky_pixels = bytearray()
for y in range(400):
    t = y / 399
    r, g, b = (lerp(top[i], bottom[i], t) for i in range(3))
    sky_pixels += bytes((b, g, r, 255)) * 600
sky = document.createNode("Sky", "paintlayer")
root.addChildNode(sky, None)
sky.setPixelData(bytes(sky_pixels), 0, 0, 600, 400)

hill_pixels = bytearray()
for y in range(400):
    for x in range(600):
        inside = ((x - 300) / 260) ** 2 + ((y - 400) / 120) ** 2 <= 1
        hill_pixels += bytes((0x38, 0x54, 0xC2, 255)) if inside else bytes((0, 0, 0, 0))
hill = document.createNode("Hill", "paintlayer")
root.addChildNode(hill, None)
hill.setPixelData(bytes(hill_pixels), 0, 0, 600, 400)

document.refreshProjection()
document.setBatchmode(True)
path = os.path.join(LMM_WORK_DIR, "postcard.kra")
saved = document.saveAs(path)
result = {"saved": saved, "kra_bytes": os.path.getsize(path), "layers": [node.name() for node in document.topLevelNodes()]}

La réponse du Hub

Réponse du Hub
{
  "app": "krita",
  "duration_ms": 1060,
  "error": null,
  "result": {
    "kra_bytes": 110725,
    "layers": [
      "Background",
      "Sky",
      "Hill"
    ],
    "saved": true
  },
  "status": "ok",
  "stderr": "",
  "stdout": "",
  "truncated": false
}

Le script a duré 1,06 s. Le document a trois calques, parce qu’un nouveau document de Krita commence avec un calque Background que le script a laissé intact, sous Sky et Hill. get_state a ensuite décrit le document et renvoyé une capture de sa projection :

Réponse du Hub
{
  "app": "krita",
  "app_version": "5.2.9",
  "bridge_version": "1",
  "captured_at": "2026-10-21T12:47:50.526Z",
  "connected": true,
  "content_origin": "document",
  "screenshot": "$XDG_RUNTIME_DIR/libremodular-mcp/captures/krita-20261021T124750502Z.png",
  "state": {
    "document": {
      "active_layer": "{727e9cd9-e6e1-423c-ade7-1bf29d6d5289}",
      "color_depth": "U8",
      "color_model": "RGBA",
      "color_profile": "sRGB-elle-V2-srgbtrc.icc",
      "height": 400,
      "layers": [
        {
          "id": "{69f5540d-2916-4771-8df7-1fcad46b677f}",
          "name": "Background",
          "opacity": 255,
          "type": "paintlayer",
          "visible": true
        },
        {
          "id": "{ed307be8-5a93-4b16-8739-7508916ea687}",
          "name": "Sky",
          "opacity": 255,
          "type": "paintlayer",
          "visible": true
        },
        {
          "id": "{727e9cd9-e6e1-423c-ade7-1bf29d6d5289}",
          "name": "Hill",
          "opacity": 255,
          "type": "paintlayer",
          "visible": true
        }
      ],
      "name": "Postcard",
      "width": 600
    }
  },
  "warnings": []
}

L’image produite

La capture est l’image fusionnée que Krita affiche, de 600 par 400 pixels. Les pixels qu’on y lit valent #1C385C en haut, #29A196 en bas et #C25438 dans la colline, les trois couleurs que le texte demandait. Le fichier .kra que le script a enregistré fait 110 725 octets.

Un dégradé vertical du bleu foncé au turquoise, avec une demi-ellipse cuivre qui monte du bord inférieur.
La capture du document Postcard après le script, telle que le Hub l'a exportée.

Guide de référence dans le dépôt →

SuiteBlender →