Load MultipassBitmap [SOLVED]

On 20/10/2015 at 04:10, xxxxxxxx wrote:

Hi there,

I couldn't find a way to load a MultipassBitmap from a file. The constructor already requires to define the
resolution and bitdepth of the MultipassBitmap. If I initialize it with 0, 0, 0 and use InitWith() (inherited
from BaseBitmap), a StandardError is raised with the message "This operation can only handle
BaseBitmaps.".

TIA,
Niklas

On 21/10/2015 at 01:37, xxxxxxxx wrote:

Hello,

to load images with layers you can use the functions of BodyPaint. Something like this:

  
bc = c4d.BaseContainer()  
bc.SetFilename(c4d.LOADTEXTURE_FILENAME, path)  
  
tex = c4d.modules.bodypaint.SendPainterCommand(c4d.PAINTER_LOADTEXTURE, doc=doc, tex=None, bc=bc)  
  
if tex is None:  
     return  
  
layer = tex.GetFirstLayer()  
  
while layer is not None:  
     print(layer.GetName())  
     layer = layer.GetNext()  

See also "Parsing PSD layers in MultipassBitmap".

best wishes,
Sebastian

On 21/10/2015 at 03:20, xxxxxxxx wrote:

Thanks Sebastian, that should be sufficient for my purpose, I don't need it as a MultipassBitmap. :)
Only that I'd like to show the image in the Picture Viewer, but I guess that won't work with a PaintTexture.

Cheers!

On 22/10/2015 at 10:09, xxxxxxxx wrote:

Hey Sebastian, I just had some time to look at the bodypaint module and its classes. It seems like I can't
read or write the pixels of a PaintLayerBmp. So there is no way to load an image with multiple layers and
use that in Python?

Thanks,
-N

On 22/10/2015 at 10:59, xxxxxxxx wrote:

They're gone until Monday Niklas.
But maybe this will help.

#This script gets the color data from a BP layer and creates an image from it  
#NOTE: GetSelectedTexture() is only supported in R16++  
  
import c4d  
def main() :  
  
  #Get the selected bp texture(Usually the image in a material)  
  tex = c4d.modules.bodypaint.PaintTexture.GetSelectedTexture()  
  texturename = tex.GetFilename()  
  
  #Get the active BP layers (the layer tab in the AM)  
  activelayer = tex.GetActive()  
  
  #If the active layer is holding a bitmap image  
  if activelayer.IsInstanceOf(c4d.OBJECT_PAINTLAYERBMP) == True:  
        
      #Convert the layer to an image and store it in memory  
      #Then get it's size values  
      bmp = activelayer.ToPaintLayerBmp()  
      xres = bmp.GetBw()  
      yres = bmp.GetBh()  
      size = xres * yres          
      if size == 0: return  
        
      #Get the color mode of the image that's in memory          
      colorMode = bmp.GetColorMode()     
           
      #Store some buffer like data into memory  
      sq = c4d.storage.ByteSeq(None, size*c4d.COLORBYTES_RGB)          
      inc = 3  
        
      #Read the color data in the image that's currently in memory  
      #Reminder: This image was gotten from a layer..Which was gotten from a channel in a material  
      for row in xrange(yres) :  
          offset = sq.GetOffset(row*(xres*inc))  
          bmp.GetPixelCnt(0, row, xres, offset, colorMode, c4d.PIXELCNT_0)   
    
      #Create a new image based on the color data we just got above  
      newBitmap = c4d.bitmaps.BaseBitmap()  
      newBitmap.Init(xres,yres,)  
      for row in xrange(yres) :  
          offset = sq.GetOffset(row*(xres*inc))   
          newBitmap.SetPixelCnt(0, row, xres, offset, inc,colorMode, c4d.PIXELCNT_0)   
        
      #Save the image to a file on your HD  
      filename = c4d.storage.SaveDialog(title="Save Image")  
      newBitmap.Save(filename,c4d.FILTER_TIF)  
  
if __name__=='__main__':  
  main()

-ScottA

On 22/10/2015 at 12:35, xxxxxxxx wrote:

Hey Scott, thanks a lot for your example! I missed that GetPixelCnt() and SetPixelCnt() are for getting
and setting pixel data (I find the names rather confusing for that purpose). Anyway, that is actually exactly
what I needed. :)

On 22/10/2015 at 15:38, xxxxxxxx wrote:

I couldn't get allocating a new  PaintTexture to work (was always size 0, 0). I also tried copying the 
contents of the PaintTexture loaded with SendPainterCommand()  to a MultipassBitmap , but the result
was just black. Also, I couldn't get layers to work with the MultipassBitmap. Although the layers were
there (ie. were returned with .GetLayers()) the Picture Viewer didn't show them.

I'll try it in C++ and see if it works there.

On 26/10/2015 at 01:49, xxxxxxxx wrote:

Hello,

as Scott pointed out the content of a PaintTexture can be read with GetPixelCnt(). See also "Bodypaint Layer Bitmap".

best wishes,
Sebastian