Is there a way to save the live brush preview of a given brush preset as an image?

You’re very welcome.

I got the same result, it’s likely switching between brushes too fast for each preview to be displayed or generated in time.

If we give a reasonable delay between switching brushes it has time to update the live previews. The yield statements are in milliseconds.

import os
from krita import *

def async_runner(func):
    """Decorator to automatically handle function execution with pauses."""
    import functools
    @functools.wraps(func)
    def wrapper():
        generator = func()
        def step():
            try:
                delay = int(next(generator))
                QTimer.singleShot(delay, step)  # Schedule next step
            except StopIteration:
                print('--- DELAYED EXECUTION COMPLETE ---')
        step()  # Start execution
    return wrapper

@async_runner
def func():

    # initialize Krita
    K = Krita.instance()
    ACTIVE_WINDOW = K.activeWindow()

    def save_preset(name, preset, directory):
        # locate brush previewer
        qmwin = ACTIVE_WINDOW.qwindow()
        presets_editor = qmwin.findChild(QWidget, "KisPaintOpPresetsEditor")
        brush_previewer = presets_editor.findChild(QGraphicsView, "liveBrushPreviewView")
        # extract and save
        pixmap = brush_previewer.grab()
        filename = os.path.join(directory, name + '.png')
        return pixmap.save(filename)


    # directory = "Desktop/presets"
    directory = R"C:\krita\brush\batch"
    # get all presets
    ALL_PRESETS = K.resources("preset")
    # save live-previews of nine presets
    maximum = 10
    presets = set()
    for preset_no, (name, preset) in enumerate(ALL_PRESETS.items(), start=1):
        if preset_no == maximum:
            break
        yield 50
        ACTIVE_WINDOW.activeView().setCurrentBrushPreset(preset)
        yield 50
        presets.add(ACTIVE_WINDOW.activeView().currentBrushPreset().name())
        save_preset(name, preset, directory)
    print(len(presets)) # output should imply that this is equal to 1, but it's 9.

    # yield 0
func()

2 Likes