Hello @bentraje,
Thank you for reaching out to us. Your question is missing a key piece of information, which color management mode your render document is in. I assume your render document is either in Basic mode and has Linear Workflow enabled, or you are in OCIO mode.

Fig. I: The color management settings of document, press CTRL + D
to open the Attribute Manager on them.
From this follow a few problems.
- There are known (and worked on bugs) with OCIO and SDR (8) and HDR (16+) bit depths and the render settings, the problem is quite complicated. In the end, this results in 8 bit images sometimes being treated as 16 bit images and then already pre-transformed 8 bit data being transformed again by the Picture Viewer.
- Your problem seems to be related to this, as neither the renderer nor the picture viewer do update the bitmap color profile of the render bitmap when you deviate from the default non-linear sRGB color management. Your script does not make any attempt to rectify this, resulting in different outputs.
- You currently lack the tools to cover all cases manually in Python, specifically you are unable to handle the OCIO case.
- There is also another bug with the PV causing a crash, when you try to invoke
ShowBitmap
without having opened the PV once first.
I will talk with the OCIO developer about (2.) as I we were already going to talk about (1.) next week. For (3.) we would have to fix BaseBitmap.SetColorProfile
, I have created a task for that, but I am not sure when we will find the time to actually fix it.
Solutions
- We could fix
RenderDocument
. This could either happen en-passant by fixing problem (1.) which is tied to how the bitmaps of a render buffer are handled. Or we could fix the method itself, but this will probably take some time, as at least I would classify this of low priority since there are other ways to deal with this.
- Using the render queue or the Teams renderer module should rectify the problem, as you then do not have to manage the bitmap color profiles.
- Handle the color profile of the bitmap manually, you can however only do this partially due to being unable to set the OCIO transforms of a bitmap in Python. Find below an example for handling at least the Linear Workflow case.
Cheers,
Ferdinand
Result:
import c4d
doc: c4d.documents.BaseDocument # The active document.
def main():
"""
"""
rd: c4d.BaseContainer = doc.GetActiveRenderData().GetClone().GetData()
bmp: c4d.bitmaps.BaseBitmap = c4d.bitmaps.BaseBitmap()
bmp.Init(int(rd[c4d.RDATA_XRES]), int(rd[c4d.RDATA_YRES]), 32)
# #bmp currently has the default sRGB 1966-2.1 color profile, i.e., a profile for an SDR color
# space with a gamma of ~2.1. When the render document has either "Linear Workflow" or OCIO
# enabled, this is not the correct render space.
# Set the color profile to linear when the document in "Linear Workflow" mode.
if (doc[c4d.DOCUMENT_COLOR_MANAGEMENT] == c4d.DOCUMENT_COLOR_MANAGEMENT_BASIC and
doc[c4d.DOCUMENT_LINEARWORKFLOW]):
bmp.SetColorProfile(c4d.bitmaps.ColorProfile.GetDefaultLinearRGB())
# Set the OCIO color profiles when a document is in OCIO mode. This is currently not possible
# in Python.
elif doc[c4d.DOCUMENT_COLOR_MANAGEMENT] == c4d.DOCUMENT_COLOR_MANAGEMENT_OCIO:
pass
res: int = c4d.documents.RenderDocument(doc, rd, bmp, c4d.RENDERFLAGS_EXTERNAL)
if res == c4d.RENDERRESULT_OK:
c4d.bitmaps.ShowBitmap(bmp)
if __name__ == '__main__':
main()