Get material / texture resolution.

I use below code to get the image resolution from a material.

shader = mat[c4d.MATERIAL_COLOR_SHADER]
matTextureFileName = shader[c4d.BITMAPSHADER_FILENAME]
bm = bitmaps.BaseBitmap(matTextureFileName)  
bm.InitWith(matTextureFileName)
width, height = bm.GetSize()

But I guess the file is loaded into memory to get the information (and that takes time).
Is it possible to get this information without 'loading' the image texture file?
So, how to get the info from the file header or from the material?

f1d4984f-0419-4f9b-aebd-b9fb2d92861d-image.png

Hello @pim,

thank you for reaching out to us. First of all, there are two slightly ambiguous things about your question:

  1. You talk about the 'resolution from a material', which would be in the most sensible interpretation the preview size of a material, i.e., MATERIAL_PREVIEWSIZE, but the rest of your question rather implies that you want to know the dimensions of a bitmap file. I will answer the latter case.
  2. Your question also implies that every bitmap would carry its resolution in its metadata/header. That is not the case in the creative chaos that is bitmap file formats and their real-life implementations.

There is no straight answer to this, but:

  1. Bitmap metadata can be read with BaseBitmap.GetData, most fields are usually not set and there is no width or height field. See end of posting for an example.
  2. The type BaseBitmap is a wrapper for the maxon API type ImageInterface. It is best to use ImageInterface directly, but that is currently only possible in C++. There you also have more granular image metadata access.
  3. You claim 'that [it] takes time" to compute the width and height, but I do not see any indication for that. The computation seems efficient to me and operates on the memory layout of the bitmap.
  4. You could try to use something like pillow when you are unsatisfied with the speed of BaseBitmap/ImageInterface. But I doubt that this will be faster.

So, long story short: Just use the methods on BaseBitmap. If there are any performance problems, I would ask you to provide example data and code, because I cannot see anything problematic here.

Cheers,
Ferdinand

Code:

import c4d

def main() -> None:
    """
    """
    bmp: c4d.bitmaps.BaseBitmap = c4d.bitmaps.BaseBitmap()
    res, _ = bmp.InitWith("e:\\misc\\particles.png")
    if res != c4d.IMAGERESULT_OK:
        return

    print(f"{bmp.GetData(c4d.BASEBITMAP_DATA_GUIPIXELRATIO, None) = }")
    print(f"{bmp.GetData(c4d.BASEBITMAP_DATA_DPI, None) = }")
    print(f"{bmp.GetData(c4d.BASEBITMAP_DATA_ASPECTRATIO, None) = }")
    print(f"{bmp.GetData(c4d.BASEBITMAP_DATA_EXPORTSETTINGS, None) = }")
    print(f"{bmp.GetData(c4d.BASEBITMAP_DATA_NAME, None) = }")

    c4d.bitmaps.ShowBitmap(bmp)

if __name__ == "__main__":
    main()

Result:

bmp.GetData(c4d.BASEBITMAP_DATA_GUIPIXELRATIO, None) = None
bmp.GetData(c4d.BASEBITMAP_DATA_DPI, None) = 72.0
bmp.GetData(c4d.BASEBITMAP_DATA_ASPECTRATIO, None) = 1.0
bmp.GetData(c4d.BASEBITMAP_DATA_EXPORTSETTINGS, None) = None
bmp.GetData(c4d.BASEBITMAP_DATA_NAME, None) = None

MAXON SDK Specialist
developers.maxon.net

Thanks for the good explanation and the example.

Regards,
Pim