Hi
I’m not a big fan of “action” trigger, even if sometime it’s the only way to execute things.
I really prefer to use API when possible.
Concerning this case, I tried your solution and for me it was harder to code than my first solution due to many crashes occurred…
There’s still something wrong with the waitForDone()
method…
Here’s the code with triggered action:
from krita import *
from PyQt5.Qt import *
def sleep(value):
loop = QEventLoop()
QTimer.singleShot(value, loop.quit)
loop.exec()
def createDoc():
"""Create a new document and return document"""
doc=Krita.instance().createDocument(800, 600, "Testing animation", "RGBA", "U8", "", 300.0)
doc.setFramesPerSecond(24)
Krita.instance().activeWindow().addView(doc)
return doc
def insertFrame(doc, layer, imgNumber):
"""Insert a frame in document"""
Krita.instance().action('insert_keyframe_right').trigger()
sleep(250)
doc.waitForDone()
image=setFrame(doc, imgNumber)
ptr = image.bits()
ptr.setsize(image.byteCount())
layer.setPixelData(QByteArray(ptr.asstring()), 0, 0, image.width(), image.height())
def setFrame(doc, number):
"""Draw and set frame content"""
# create an empty image with current document size
pixmap=QPixmap(doc.bounds().size())
# set image as fully transparent
pixmap.fill(QColor(Qt.transparent))
# define black border, 2 pixels witdh
pen=QPen(Qt.black)
pen.setWidth(2)
# define background color from Hue/Saturation/Value
color=QColor.fromHsl(number, 255, 128, 255)
brush=QBrush(color)
# create painter
painter=QPainter()
# start to draw
painter.begin(pixmap)
# define pen & fill color
painter.setPen(pen)
painter.setBrush(brush)
# do transformation in space (rotate center of a rectangle draw at the center of image)
painter.translate(400,300)
painter.rotate(number)
# draw rectangle
painter.drawRect(QRect(-200,-150,400,300))
painter.end()
# return image
return pixmap.toImage()
def main():
doc=createDoc()
layer=doc.createNode("Animated layer", "paintlayer")
doc.rootNode().addChildNode(layer, None)
for i in range(360):
insertFrame(doc, layer, i)
main()
As you can see, there’s a sleep()
of 250ms after the Krita.instance().action('insert_keyframe_right').trigger()
and before the doc.waitForDone()
-
With the sleep()
call, it’s loooong to generate animation
250ms * 360, it’s ~90s to generate animation (first method need ~11s to generate animation)
-
Without the sleep()
call or if I reduce this sleep value, Krita badly crash after the following warning on console:
SAFE ASSERT (krita): "!m_d->waitingOnImages.contains(image)" in file /home/appimage/workspace/Krita_Release_Appimage_Build/krita/libs/image/KisBusyWaitBroker.cpp, line 64
SAFE ASSERT (krita): "m_d->waitingOnImages.contains(image)" in file /home/appimage/workspace/Krita_Release_Appimage_Build/krita/libs/image/KisBusyWaitBroker.cpp, line 80
SAFE ASSERT (krita): "!m_d->waitingOnImages.contains(image)" in file /home/appimage/workspace/Krita_Release_Appimage_Build/krita/libs/image/KisBusyWaitBroker.cpp, line 64
SAFE ASSERT (krita): "m_d->waitingOnImages.contains(image)" in file /home/appimage/workspace/Krita_Release_Appimage_Build/krita/libs/image/KisBusyWaitBroker.cpp, line 80
ASSERT (krita): "row >= 0" in file /home/appimage/workspace/Krita_Release_Appimage_Build/krita/plugins/dockers/animation/kis_animation_curve_channel_list_model.cpp, line 143
Grum999