Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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
    • Login

    ShowBitmap() from website URL

    Cinema 4D SDK
    python r25
    2
    3
    391
    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.
    • gheyretG
      gheyret
      last edited by

      Hi! plugincafe~
      I try to get an image from website, And ShowBitmap() in C4D python.
      This is my simple code:

      import c4d
      from c4d import gui, bitmaps
      
      def main():
          img = "https://images.pexels.com/photos/10204089/pexels-photo-10204089.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"
          bmp = bitmaps.BaseBitmap()
          a,b = bmp.InitWith(img)
          print(a,b)
          if a == c4d.IMAGERESULT_OK:
              bitmaps.ShowBitmap(bmp)
          bmp.FlushAll()
          
      # Execute main()
      if __name__=='__main__':
          main()
      

      Sometimes it can ShowBitmap() correctly like this:
      01.jpg

      Sometimes it's can show bitmap but the image is not loaded correctly:
      02.jpg

      And sometimes it's faild! And the InitWith() result is -6
      Is there have some right way to show an image from the URL?

      www.boghma.com

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

        Hello @gheyret,

        Thank you for reaching out to us. The reason why this is failing for you is due to you not caching the content you want to put into the BaseBitmap or alternatively not using a high-level-enough interface.

        You can download the content of the image at your URL into either a temporary cache file or an in-memory file or use LoadFile and let Cinema 4D handle the rest. Find a simple example for each approach at the end of my posting.

        When you are still running into problems, you should first try to see if you can access the whole file in principle. For example, with urllib3 which I am using in the code below.

        Cheers,
        Ferdinand

        The result:
        fc64eb70-9aa6-4be7-b243-bacc3f047474-image.png

        The code:

        """Simple example for displaying three different images, referenced by an HTTP 
        scheme url each, in the Picture Viewer.
        """
        
        import c4d
        import urllib3
        
        def main():
            """Shows three approaches for how to display an image in the picture
            viewer that has a http(s) url scheme.
            """
        
            # Your image url, make sure to escape paths properly or to use raw strings 
            # as I do here.
            url = (r"https://images.pexels.com/photos/10204089/pexels-photo" +
                   r"-10204089.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500")
        
            # Your and my forum avatar as png images.
            urlGheyret = (r"https://developers.maxon.net/forum/assets/uploads/profile/" + 
                          r"256-profileavatar-1631789551927.png")
            urlFerdinand = (r"https://developers.maxon.net/forum/assets/uploads/profile/" + 
                            r"1024-profileavatar.png")
        
        
            # The interface to make requests with in urllib3.
            poolManger = urllib3.PoolManager()
        
            # Approach I:
        
            # Attempt to connect to the url.
            response = poolManger.request('GET', url)
            if response.status != 200:
                raise RuntimeError(
                    f"Could not access {url} with the code: {response.status}.")
        
            # Write the image to a local file.
            tempFile = "e:\\cache.tmp"
            with open(tempFile,"wb") as f:
                f.write(response.data)
        
            # Load the file as a BaseBitmap into the PictureViewer.
            bmp = c4d.bitmaps.BaseBitmap()
            result, isMoviev = bmp.InitWith(tempFile)
        
            if result != c4d.IMAGERESULT_OK:
                raise RuntimeError(
                    "Could not initialize BaseBitmap with downloaded content.")
        
            # Show the bitmap.
            c4d.bitmaps.ShowBitmap(bmp)
        
            # We do not need to flush any bitmaps here, since the bitmap is being 
            # deallocated by scope and #ShowBitmap() makes a copy anyways.
        
            # Approach II:
        
            # Get your forum avatar.
            response = poolManger.request('GET', urlGheyret)
            if response.status != 200:
                raise RuntimeError(
                    f"Could not access {url} with the code: {response.status}.")
        
            # Load the data from the response into a MemoryFileStruct and try to
            # initialize a bitmap with it.
            byteArray = bytearray(response.data)
            memFile = c4d.storage.MemoryFileStruct()
            memFile.SetMemoryReadMode(byteArray, len(byteArray))
        
            bmp = c4d.bitmaps.BaseBitmap()
            result, isMoviev = bmp.InitWith(memFile)
        
            if result != c4d.IMAGERESULT_OK:
                raise RuntimeError(
                    "Could not initialize BaseBitmap with downloaded content.")
        
            # Show the bitmap.
            c4d.bitmaps.ShowBitmap(bmp)
        
            # Approach III:
        
            # Approach is a bit of an overstatement here, but internally, i.e., in
            # C++, we use the maxon API for such stuff, specifically the maxon:Url
            # type, which hides most of these downloading shenanigans away. And
            # while maxon::UrlInterface has already been exposed to Python as
            # maxon.UrlInterface, some tidbits are still missing, to make a more
            # low-level use of it. But we can call a high-level interface with a
            # url string (or Filename in terms of the classic API) and let the 
            # core do its thing. In this case it simply means calling LoadFile(). This
            # will however not expose the BaseBitmap, and instead just load the image
            # into the picture viewer. You will also get GUI events in some cases, as 
            # for example when you attempt to load the same url twice, as Cinema 4D
            # will ask you then if you really want to do that.
        
            # Load the image at #urlFerdinand into Cinema 4D, which will reflect as
            # it being loaded into the Picture Viewer.
            c4d.documents.LoadFile(urlFerdinand)
        
        
        if __name__ == '__main__':
            main()
        

        MAXON SDK Specialist
        developers.maxon.net

        gheyretG 1 Reply Last reply Reply Quote 1
        • gheyretG
          gheyret @ferdinand
          last edited by

          @ferdinand
          Wow! you perfectly solved my problem!
          Thank you! 🍻

          www.boghma.com

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