ImageSets in Python

This is a quick very beginner guide to how Mari handles images using Python. I found it initially a little confusing when first learning, so here is a quick look at how to get to the image level in simple terms. 
Note: Some very basic understanding of Python is assumed.

Before we can do any manipulation to images in Mari, we have to find them first. To find them, we start at the geometry, known in Mari as a geoEntity. Here we define our currently selected geo:

marigeo = mari.geo.current()

This geoEntity object will be the basis for defining all info you need. Next we find and assign the current channel for this geo:

marichannel = marigeo.currentChannel()

We now have a channel to dissect. Channel and LayerStack classes can both be used on this new channel object, each class controls different aspects of the whole channel. Channel will allow more global control, while LayerStack specifically controls layers.

Now we want to pinpoint a layer to manipulate, it is possible to find layers a few different ways, to find the current selected layer, we can make the following assignment:

marilayer = marichannel.currentLayer()

Alternatively, we can also specify the name of a layer to assign:

marilayer = marichannel.layer('My Layer')

Once we have defined our layer, we can then proceed to finding its images. A layer can consist of multiple parts, the paintable layer (if layer is paintable), a mask or mask stack, and an adjustment stack. The paintable portion of a layer is considered an imageSet. The imageSet is a package of images, 1 image per patch. In order to do any operation to an image (save, copy, resize, etc), we have to pull it out of its imageSet. For the purposes of this guide I am just going to just cover the paintable imageSet.

We will need two things to find our images, the first is the imageSet, and the second is the uvIndex (UDIM position). First we need to pinpoint the imageSet that is attributed to the paintable portion of the layer:

mariImgSet = marilayer.imageSet()

Now that we have the set of images, we can isolate one or iterate through them. As mentioned before, we need to also supply a UDIM coordinate, so Mari knows which image you want. The image class wants to use "uv index", which is just the UDIM number minus 1001. For example uv index of 1001 is 0, and the uv index of 1034 is 33, and so on.

To isolate just one image from the imageSet, lets choose the 1001 UDIM, the second parameter seen is the frame number (-1 is the default key frame). After assigning our parameters, we can fill it with a color.
Note: Mari uses its own color class called Color)

redColor = mari.Color(1,0,0,0)
mariImg = mariImgSet.image(0,-1)
mariImg.fill(redColor)

Alternatively, we can save the image out:

mariImg.saveAs(r'/home/images/test.tif')

However, itterating over these imageSets is the ultimate goal in most cases. In order to do this, we need two lists, one list of images and one list of patches, here is how we find the patches:

mariPatchList = marigeo.patchList()

Here we just set up a loop to modify each patches image:
Note: We can use the .uvIndex() method to find the uv index of the geoPatch.

for patch in mariPatchList:
    uv = patch.uvIndex()
    patchImg = mariImgSet.image(uv,-1)
    patchImg.fill(redColor)

Alternatively, we can save each image out:
Note: We can also find the UDIM of a patch by using the .udim() method of the geoPatch.

for patch in mariPatchList:
    uv = patch.uvIndex()
    udim = str(patch.udim())
    patchImage = mariImgSet.image(uv,-1)
    patchImg.saveAs('/home/images/test.%s.tif' % udim)

And finally, if we put it all together in a single function, it might look like this:
def saveImage():
"""A simple test function"""
###Mari info - find all our currently selected items.
marigeo = mari.geo.current()
mariPatchList = marigeo.patchList()
marichannel = marigeo.currentChannel()
marilayer = marichannel.currentLayer()
mariImgSet = marilayer.imageSet()
###Color
redColor = mari.Color(1,0,0,1)

###Loop through patches
for patch in mariPatchList:
    uv = patch.uvIndex()
    udim = str(patch.udim())
    patchImg = mariImgSet.image(uv,-1)
    patchImg.fill(redColor)
    patchImg.saveAs(r'/home/images/test.%s.tif' % udim)