Loading BaseBitmap from memory



  • I am using PIL to create thumbnails.
    In order to use these thumbails in DrawMsg(), they must be Bitmaps and not a buffer memory.
    PIL returns the converted image in memory.

    So, the question is how to convert this memory to a Bitmap?
    At this moment I store the thumbnail in a file and load that file back in the BaseBitmap.

    bmp = c4d.bitmaps.BaseBitmap()
    
    image = Image.open(...)
    MAX_SIZE = (100, 100)
    image.thumbnail(MAX_SIZE)
    
    # Saving files
    save = os.path.join(...)            #save result in file      
    image.save(save)
    
    bmp.InitWith(save)               # load file into bitmap
    
    # draw bitmap
    self.DrawBitmap(bmp, x1, y1, 100, 100, 0, 0, 100, 100, c4d.BMP_NORMAL)
    

    I also tried to use mfs, but no success

    bmp = c4d.bitmaps.BaseBitmap()
    hf = storage.HyperFile()
    mfs = storage.MemoryFileStruct()
    
    image = Image.open(img)
    MAX_SIZE = (100, 100)
    image.thumbnail(MAX_SIZE)
    
    mfs.SetMemoryReadMode(image.fp.read(), len(image.fp.read()))
    
    if hf.Open(0, mfs, c4d.FILEOPEN_READ, c4d.FILEDIALOG_NONE):
        bmp = hf.ReadImage()
    
    bmp.InitWith(save)bmp.Init(100, 100, depth=16, flags=c4d.INITBITMAPFLAGS_0)
    self.DrawBitmap(bmp, x1, y1, 100, 100, 0, 0, 100, 100, c4d.BMP_NORMAL)
    
    
    


  • I'm not an expert on PIL, but it seems to have a getpixel() method. So you should be able to read each pixel value and write it into a BaseBitmap with SetPixel().



  • Good point, thanks.
    On the other hand, copying pixel seems a bit of an overkill.
    A memory buffer is just an address and a length. To me this looks a lot like a BaseBitmap.



  • Hi @pim unfortunately, this is not possible.

    The Pil memory model is probably way different than our BaseBitmap object, so if it would have been the exact same data structure, it would have been possible, but since this is 2 different objects (so different memory layout) I don't see a way to make it work.

    @PluginStudent advice is good, you should read and write all pixels manually, but as you figured it out, this is slow, so you should cache it and probably not doing it into the DrawMsg.

    Cheers,
    Maxime.



  • Thanks, I understand.
    I am now going to do it outside DrawMsg in parallel (thread) plugin.
    See my other post.
    https://plugincafe.maxon.net/topic/12310/best-plugin-type-for-background-thread-processing

    -Pim


Log in to reply