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

    HyperFile bitmap Raw data [SOLVED]

    Scheduled Pinned Locked Moved PYTHON Development
    8 Posts 0 Posters 703 Views
    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.
    • H Offline
      Helper
      last edited by

      On 24/11/2016 at 04:19, xxxxxxxx wrote:

      Is there a way to achieve this things:

              path = os.path.join(tempfile.gettempdir(), 'image_buffer.png')
              if bmp.Save(path, c4d.FILTER_PNG) != c4d.IMAGERESULT_OK:
                  return False
        
              f = open(path, "rb")
              bmp_data = f.read()
              f.close()
        
              os.remove(path)
        
              return bmp_data
      

      But with hyperFile instead of using a buffer image wich I guess  using the memory will be a bit more faster than using the HDD as a buffer.
      And moreover is there a way for deleting content of an hyperfile (I was looking for free the memory used by hyperfile)

      I tried hyperfile.writeImage and then ReadData but this not return the same output as the one writtend before.

      Thanks in advance ! 🙂

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 25/11/2016 at 01:17, xxxxxxxx wrote:

        Hello,

        Honestly, I'm not fully understanding what you want to achieve.

        Do you want to load a BaseBitmap from a file? You can do that with BaseBitmap.InitWith().
        Do you want to store BaseBitmap data in a HyperFile? You can do that with HyperFile.WriteImage() and HyperFile.ReadImage().
        Do you want to use a HyperFile but not to save the data on the hard drive, only in memory? You can use the HyperFile with a MemoryFileStruct.

        You find an example on how to use these classes in MemoryFileBitmap.py.

        best wishes,
        Sebastian

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 25/11/2016 at 09:24, xxxxxxxx wrote:

          I just want the hex representation of a file. In my case a png. Cause I store this picture into a database.
          So I want to store png file (not an basebitmap since I retrieve it later).

          Yes it's exactly your third sentence. But using the exemple provided in the exempel just return None...

          import c4d
          class Picture(object) :
            
              @staticmethod
              def get_raw_data(bmp, format=c4d.FILTER_JPG,settings=c4d.BaseContainer()) :
                  """
                  Write an hyper file image to a buffer object
                  
                  @return: The byte sequence or None
                  
                  @img: The image to convert into a buffer object
                  @format: The filter type
                  @settings: Optional settings
                  """
                  mfs = c4d.storage.MemoryFileStruct()
                  mfs.SetMemoryWriteMode()
            
                  #Si c'est un png on save l'alpha
                  if format == c4d.FILTER_PNG:
                      settings[c4d.SAVEBIT_ALPHA] = True
                  
                  hf = c4d.storage.HyperFile()
                  if hf.Open(0, mfs, c4d.FILEOPEN_WRITE, c4d.FILEDIALOG_NONE) :
                      if not hf.WriteImage(bmp,format,settings) :
                          return None
                      hf.Close()
                  byteseq, size = mfs.GetData()
                  print byteseq
                  return byteseq, size
            
              @staticmethod
              def read_hyper_file(byteseq) :
                  """
                  Creates a bitmap from a buffer object.
                  
                  @return: The image if succeeded, otherwise False
                  
                  @byteseq: The buffer object.
                  """
                  
                  bmp = c4d.bitmaps.BaseBitmap()
                  hf = c4d.storage.HyperFile()
                  mfs = c4d.storage.MemoryFileStruct()
                  
                  bmp = None
                  mfs.SetMemoryReadMode(byteseq, len(byteseq))
                  if hf.Open(0, mfs, c4d.FILEOPEN_READ, c4d.FILEDIALOG_NONE) :
                      bmp = hf.ReadData()
                      hf.Close()
                  
                  return bmp
          

          As you can see I use ReadData instead of ReadImage cause I don't want a basebitmap I want raw value like I did in my first script when I just save an image, read it and store this data.

          Anyway thanks in advance.

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            On 28/11/2016 at 00:16, xxxxxxxx wrote:

            Hello,

            so you want the binary data of some PNG encoded bitmap?

            You cannot use ReadData() instead of ReadImage(). ReadData() is the equivalent of the C++ function HyperFile::ReadGeData() so it has nothing to do with your task.

            The only way to get the "internal" data of the HyperFile is to use a MemoryFileStruct target as shown in the script. But that data would not only include the bitmap data but also any meta data of the actual HyperFile and stored BaseBitmap.

            So I'm afraid it might not be possible to do what you want just using the Cinema API. But maybe there are some functions in the Python standard libs that you could use.

            best wishes,
            Sebastian

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              On 28/11/2016 at 00:56, xxxxxxxx wrote:

              Thanks for your answerd !

              Yes I want the binary data of a PNG bitmap from a BaseBitmap.

              I'm not sure to fully understand the difference beetwen an hyperfile and a MemoryFileStruct.
              But if MemoryFileStruct contening the binary represation of a BaseBitmap + Hyperfile + Bitmap.
              Does that mean if I store this binary I can restore it later? Normally yes but I prefer to ask.

              Is there a way to get this structure? Cause with struct python library I will be able to only get the bitmap.

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                On 28/11/2016 at 09:01, xxxxxxxx wrote:

                Hello,

                a MemoryFileStruct is some object in memory. One can "save" a HyperFile into such a MemoryFileStruct instead of a file on disc.

                You can restore a HyperFile from the data stored in a MemoryFileStruct. This is exactly what the MemoryFileBitmap.py script does.

                best wishes,
                Sebastian

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  On 04/12/2016 at 14:41, xxxxxxxx wrote:

                  Sry for the late reply I just got free time to go on this project and test what you said. And all is working. Moreover since it's store the basebitmap it's really cool ! 🙂

                  Here is my ulgy test code if someone is interested !
                  Do not use it in production the db management is really done badly ! Never do something like that withtout a try/except/finally cause if any of the sql command fail your db will never be closed.

                  import sqlite3
                  import c4d
                  from c4d import bitmaps, storage
                    
                  def WriteBitmap(bmp, format=c4d.FILTER_B3D,settings=c4d.BaseContainer()) :
                      mfs = storage.MemoryFileStruct()
                      mfs.SetMemoryWriteMode()
                      
                      hf = storage.HyperFile()
                      if hf.Open(0, mfs, c4d.FILEOPEN_WRITE, c4d.FILEDIALOG_NONE) :
                          if not hf.WriteImage(bmp,format,settings) :
                              return None
                          hf.Close()
                      
                      byteseq, size = mfs.GetData()
                      return byteseq, size
                    
                  def ReadBitmap(byteseq) :
                      bmp = bitmaps.BaseBitmap()
                      hf = storage.HyperFile()
                      mfs = storage.MemoryFileStruct()
                      
                      bmp = None
                      mfs.SetMemoryReadMode(byteseq, len(byteseq))
                      if hf.Open(0, mfs, c4d.FILEOPEN_READ, c4d.FILEDIALOG_NONE) :
                          bmp = hf.ReadImage()
                          hf.Close()
                      
                      return bmp
                    
                    
                  def connect_db() :
                      db = sqlite3.connect('C:\\test.db')
                      db.text_factory = bytes
                      return db
                    
                  def create_table(db) :
                      cursor = db.cursor()
                      cursor.execute('''
                          CREATE TABLE data(test BLOB)
                      ''')
                      db.commit()
                    
                    
                  def add_data(db,data) :
                      cursor = db.cursor()
                      cursor.execute('''INSERT INTO data(test)
                                    VALUES(:data)''',
                                    {'data':data})
                      db.commit()
                      
                  def get_data(db) :
                      cursor = db.cursor()
                      cursor.execute('''SELECT * FROM data''')
                      
                      all_rows = cursor.fetchall()
                      db.close()
                      
                      return all_rows
                      
                      
                  def main() :
                    
                      path = "C:\\MyPicture.jpg"
                      if not path: return
                      
                      # Create and initialize selected image
                      img = bitmaps.BaseBitmap()
                      if img.InitWith(path)[0] != c4d.IMAGERESULT_OK:
                          gui.MessageDialog("Cannot load image \"" + path + "\".")
                          return
                    
                      byteseq, size = WriteBitmap(img) # Save image to hyper file in byte sequence
                      db = connect_db()
                      create_table(db)
                      add_data(db,bytes(byteseq))
                      test = get_data(db)[0][0]
                      bmp = ReadBitmap(test) # Read image from the byte sequence
                      
                      bitmaps.ShowBitmap(bmp)
                    
                  if __name__=='__main__':
                      main()
                  

                  The trick was to use db.text_factory = bytes that force sqlite to return bytes instead of str(which fail decoding bytes.)

                  Btw could you confirm me if I do delete(memoryFileStruct) that will free the memory used by the memoryFileStruct I mean not only the object itself but also the memory where this file is pointing?

                  As said before since my plugin might be doing this function a lot of time I don't want to kill the memory by stacking something in it.

                  Anyway thanks for you reply ! 🙂

                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    On 05/12/2016 at 01:51, xxxxxxxx wrote:

                    Hello,

                    the managed memory is deleted when the MemoryFileStruct object is deleted. The standard Python garbage collection handles the deletion of the actual MemoryFileStruct object.

                    best wishes,
                    Sebastian

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