How to conver image color profile through python?

Hi, I’m wondering if there’s some batch script or something similar that would just take images in a folder, converted them all to srgb and saved, please?

You can probably do this with a tool like ImageMagick on the command line without needing Krita.

This wouldn’t work with KRA files but most other flat file types that support color management.

1 Like

I appreciate the ImageMagick but currently I’m looking for a way to convert color profiles through scripts in Krita, I found batchmode and I can get the image list through python but not sure how to convert the image color profile?

I think I’ve managed to figure out the part of batching the process but can’t figure out the conversion (in Krita you can go Image - Conver Image Color Space this seems ot be the last part I’m missing, would you perhaps please know?

I tried:

from krita import * # you need this in Scripter with InfoObject

doc = Krita.instance().activeDocument()
convert = doc.setColorProfile("sRGB-elle-V2-srgbtrc.icc")
print(convert)

But I it doesnt’ give the same result as the manual way mentioned above - the colors are quite muted and shifted though the info in color profile in the image is the same as after the manual way.

EDIT: I did give it a try in imagemagick but I can’t figure out how to convert the colorspace, I get an output file but it’s still in the same format even with commands from the manual. Bad day for me I guess :0

There is a python plugin in default Krita called “color space” you can change colour profile of multiple documents with it, maybe it can give you any clues

1 Like

Thanks a lot, that helped a lot! :slight_smile:

Just in case someone else stumbles upon this thread here is what I’m doing (I run it from the Scripter inside Krita)

It goes through a dir, checks for dirs inside and files inside (images in this case), opens the img changes it to sRGB colorSpace and exports the images into an “export” directory with the same structure as the source directory has.

from krita import *
from os import walk

print("Start")

sourceDir = "EnterYourSourceDirectoryPathHere"
exportDir = "exports"
outputDir = sourceDir + "/" + exportDir

# Prepare export directory
if not os.path.exists(outputDir):
    os.mkdir(outputDir)

fileStructure = {}
i = 0

# Get directory paths and filenames
for (dirpath, dirnames, filenames) in walk(sourceDir):
    if i == 0 and len(dirnames) > 0:
        dirNames = dirnames
        
        # Remove export directory from the list
        if exportDir in dirNames:
            dirNames.remove(exportDir)
    else:
        # Exclude export directory
        if exportDir in dirpath:
            continue

        fileStructure[dirNames[i-1]] = {
            "dirPath": dirpath,
            "files": filenames
        }
    i += 1

ks = krita.Krita.instance()

# Export settings for jpg
expParams = InfoObject()
expParams.setProperty('quality', 80)
expParams.setProperty('smoothing', 0)
expParams.setProperty('subsampling', 0)
expParams.setProperty('progressive', False)
expParams.setProperty('optimize', True)
expParams.setProperty('saveProfile', True)

#############################################
# What options can be set in setColorSpace
#colorModelsList = sorted(ks.colorModels())
#print(colorModelsList)

# colorDepths parameter comes from colorModelsList
#colorDepthsList =  sorted(ks.colorDepths("RGBA"))
#print(colorDepthsList)

# colorDepths parameters comes from colorModelsList and colorDepthsList
#colorProfilesList = sorted(ks.profiles("RGBA", "U8"))
#print(colorProfilesList)
#############################################

# Prepare base statistics about dir/file counts
filesTotal = 0
directoriesTotal = 0

for dir in fileStructure:
    directoriesTotal += 1
    
    dirInfo = fileStructure[dir]
    
    filesTotal += len(dirInfo["files"])

dirCounter = 0
fileCounterTotal = 0

for dir in fileStructure:
    newDirPath = outputDir + "/" + dir

    if not os.path.exists(newDirPath):
        os.mkdir(newDirPath)

    dirInfo = fileStructure[dir]
    
    dirCounter += 1
    fileCounter = 0
    
    for file in dirInfo["files"]:
        QApplication.processEvents()
        fileCounterTotal += 1
        fileCounter += 1
        
        if os.path.exists(newDirPath + "/" + file):
            print("File already exists " + file)
            continue
            
        print("Processing ~ (" + str(dirCounter) + "/" + str(directoriesTotal) + ") Directory: " + dir + ", (" + str(fileCounter) + "/" + str(len(dirInfo["files"])) + ") File: " + file + ", Files Total: " + str(fileCounterTotal) + "/" + str(filesTotal))
    
        doc = ks.openDocument(dirInfo["dirPath"] + "/" + file)
        doc.waitForDone()
        doc.setBatchmode(True)
        # Parameters from colorProfilesList
        doc.setColorSpace("RGBA", "U8", "sRGB-elle-V2-srgbtrc.icc")
        doc.waitForDone()
        doc.exportImage(newDirPath + "/" + file, expParams)
        doc.waitForDone()
        doc.close()
        doc.waitForDone()
        
    print("Directory " + dir + " finished, moving to next directory")
    
print("Finished")

I think it could bei mproved by importing images into one document as layers and using layer export for that but I don’t know how to do that right now and this works for me just fine too.

1 Like

@raghukamath @Takiro @tiar

I’d like to ask if you guys (or anyone else? :)) would know please.

With the code above I create a new document as:

doc = ks.openDocument(dirInfo["dirPath"] + "/" + file)

It’s ok as far as I can tell, when I’m done exporting the image with:

doc.exportImage(newDirPath + "/" + file, expParams)

(so far so good) I close the document with:

doc.close()

Now I thought this is ok and maybe it is but after going through about 550 documents my Krita just stops responding when I check the windows’s task manager it shows over the time I open/close images that the RAM usage is increasing (never actually going down) - though it goes only up to about 2.5 GB so nothing terrible I’d say from the stand point of the amount of RAM used (my system has 32 GB)

Now I’m not sure if this is related or not since with adifferent question I was told the manager isn’t reliable when it comes to RAM usage with Krita but there’s probably some reason why it stops responding?

I tried adding the lines:

doc.waitForDone()

I’m not sure what it does in this case or if it’s in my case useless but the unresponsive Krita comes after about 550 images with or without these lines.

I’m not sure if I’m doing something wrong in the code that would cause this but since it works for 500+ uses my only assumption right now is that I could be perhaps leaking something somewhere?

Would you please have any idea?

The file #550 is a big file? :slight_smile:
How much file have you in your list?

If you add a QApplication.processEvents() at the beginning of the loop, does it change anything?

Grum999

All the files are about the same size, it’s ap hoto album from the same camera same settings and when I restart krita I can start the process with this file and it just works.

I have about 4000 files right now in the queue.

I gave the QApplication.processEvents() a try but only for several minutes and so far at least the RAM usage seems to be the same.

To get more out of it I’ll need to run it for a bit longer to get up to that 550+ line but that takes a while so I’ll have to try it tomorrow and let you know here.

I wonder if the main thread has some timeout, maybe if there’s a way to run the code on a separate thread in Krita?

Or since i run it through the Scripter maybe that’s the problem, you wouldn’t maybe if I can run the python script with Krita through promp/shell/terminal in windows or something?

Thank you very much I’ll see to it as soon as I can after I wake up :slight_smile:

I’m not aware of any limitations of the scripter and the code looks fine to me. Although the manual path building bugs me a little I would use os.path.join. But that’s not part of the issue.

I rarely use python scripting in Krita, so I’m probably not of much help.

Does it always stop at thesame file?

1 Like

I would guess it’s just the problem of Krita not releasing memory after every file, but still keeping it in the tile manager? But it should reuse it… well, it might be leaking somewhere. Maybe it would be better to make a Python or bash script that calls krita runner with a script for like ~300 images, then run it again for the next 300 etc?

1 Like

@Takiro
I actually found about the join method after I finished writing the script and plan to rewrite that part in the morning :0. I’m not a python programmer so figuring out new things all the time :slight_smile:

It doesn’t stop at the same file itj ust stop after about the same number of files even during exports of other directories with different files (though all about similar file size).

@tiar
I kinda got it working with the kritarunner but it stops when it gets to line:
doc = ks.openDocument(os.path.join(dirInfo["dirPath"], file))
I don’t get any error message in DebugView but I’m not sure if there are any that are not logged there.
I tried to manually mess the path just to see what happens and that gives an error as expected.
If the path is correct the kritarunner just exits, no errors or anything it just stops.

Do you please have any idea since this works just fine through the scripter?

I made a new kritarunner thread about the document opening (since seems to be a separate thing)

Thank you very much guys.