Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Register
    • Login

    Can I convert a BaseBitmap into a Image file in memory?

    Cinema 4D SDK
    windows python 2024
    2
    3
    444
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • DunhouD
      Dunhou
      last edited by

      Hi community !

      I want to send my render images to a website, but I have to use BaseBitmap.Save to save the result and then post them, I am trying to speed this a little, and I didn't know to can I do this :

      • convert the BaseBitmap to a "normal" PNG image file in memory.
      • send the file to a server directly without write them to disk.

      Is that possible to do this?

      Cheers~
      DunHou

      https://boghma.com
      https://github.com/DunHouGo

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @Dunhou
        last edited by ferdinand

        Hey @Dunhou,

        Thank you for reaching out to us. I am a bit surprised that you ask since we recently had this thread and you liked it, so you must have seen it, but here you go. I did not double check if the MFS byte content is actually identical to a file on disk, but it should be.

        Cheers,
        Ferdinand

        """Implements a Cinema 4D python script that generates a gradient bitmap and writes it to a file
        in memory, and then prints the memory struct data to the console and displays the bitmap in the
        Cinema 4D picture viewer.
        """
        
        import c4d
        import http.client
        import itertools
        
        from mxutils import CheckType, CheckIterable
        
        def CreateTexture(size: tuple[int, int]) -> c4d.bitmaps.BaseBitmap:
            """Creates a new texture with the given size and fills it with a gradient.
            """
            CheckIterable(size, int, tuple, minCount=2, maxCount=2)
            bmp: c4d.bitmaps.BaseBitmap = CheckType(c4d.bitmaps.BaseBitmap())
            if bmp.Init(size[0], size[1]) != c4d.IMAGERESULT_OK:
                raise RuntimeError("Failed to initialize bitmap.")
        
            for x, y in itertools.product(range(size[0]), range(size[1])):
                color: c4d.Vector = c4d.Vector(x / size[0], y / size[1], 0)
                bmp.SetPixel(x, y, int(color.x * 254.99), int(color.y * 254.99), int(color.z * 254.99))
            
            return bmp
        
        def main():
            """
            """
            bmp: c4d.bitmaps.BaseBitmap = CreateTexture((256, 256))
            mfs: c4d.storage.MemoryFileStruct = c4d.storage.MemoryFileStruct()
            mfs.SetMemoryWriteMode()
        
            if bmp.Save(mfs, c4d.FILTER_PNG) != c4d.IMAGERESULT_OK:
                raise RuntimeError("Failed to save bitmap to memory file.")
            
            data: bytearray # The data of the memory file struct.
            size: int # The size of the data in the memory file struct in bytes.
            data, size = mfs.GetData()
        
            # Send the data to an endpoint using a POST request.
            # client: http.client.HTTPConnection = http.client.HTTPConnection("https://foo.net", 80)
            # if client.connect():
            #     client.request("POST", "/endpoint", body=data)
            #     response: http.client.HTTPResponse = client.getresponse()
            #     print (response.status, response.reason)
        
            # Print a hex dump of the first 32 bytes of the data in blocks of 8 bytes.
            print("Data: ")
            for i in range(0, 32, 8):
                print(" ".join(f"{b:02X}" for b in data[i:i+8]))
        
            c4d.bitmaps.ShowBitmap(bmp)
        
        if __name__=='__main__':
            main()
        

        edit: On a quick check, the output seems good:

        016c9978-9681-4627-ac51-d9e252cb99d4-image.png
        3fb8ab80-e47c-4def-bdbc-76a5d54cc76e-image.png
        https://en.wikipedia.org/wiki/List_of_file_signatures

        MAXON SDK Specialist
        developers.maxon.net

        DunhouD 1 Reply Last reply Reply Quote 0
        • DunhouD
          Dunhou @ferdinand
          last edited by

          Hey @ferdinand , oops, I have an impression of this topic and tried to recall it, but I couldn't find any keywords in my mind at the time. I must have gone crazy.

          And the key is the GetData(), I have no concept of file composition and did not realize that what is returned here is the data required for an image file. Thank you very much.

          Cheers~
          DunHou

          https://boghma.com
          https://github.com/DunHouGo

          1 Reply Last reply Reply Quote 0
          • First post
            Last post