code: def get_meta_data(self):
      # todo: there is also FreeImage_TagToString, is that useful?
      # and would that work well when reading and then saving?
  
      # Create a list of (model_name, number) tuples
      models = [
          (name[5:], number)
          for name, number in METADATA_MODELS.__dict__.items()
          if name.startswith("FIMD_")
      ]
  
      # Prepare
      metadata = Dict()
      tag = ctypes.c_void_p()
  
      with self._fi as lib:
          # Iterate over all FreeImage meta models
          for model_name, number in models:
              # Find beginning, get search handle
              mdhandle = lib.FreeImage_FindFirstMetadata(
                  number, self._bitmap, ctypes.byref(tag)
              )
              mdhandle = ctypes.c_void_p(mdhandle)
              if mdhandle:
                  # Iterate over all tags in this model
                  more = True
                  while more:
                      # Get info about tag
                      tag_name = lib.FreeImage_GetTagKey(tag).decode(
                          "utf-8"
                      )
                      tag_type = lib.FreeImage_GetTagType(tag)
                      byte_size = lib.FreeImage_GetTagLength(tag)
                      char_ptr = ctypes.c_char * byte_size
                      data = char_ptr.from_address(
                          lib.FreeImage_GetTagValue(tag)
                      )
                      # Convert in a way compatible with Pypy
                      tag_bytes = bytes(bytearray(data))
                      # The default value is the raw bytes
                      tag_val = tag_bytes
                      # Convert to a Python value in the metadata dict
                      if tag_type == METADATA_DATATYPE.FIDT_ASCII:
                          tag_val = tag_bytes.decode("utf-8", "replace")
                      elif tag_type in METADATA_DATATYPE.dtypes:
                          dtype = METADATA_DATATYPE.dtypes[tag_type]
                          if IS_PYPY and isinstance(
                              dtype, (list, tuple)
                          ):
                              pass  # pragma: no cover - or we get a segfault
                          else:
                              try:
                                  tag_val = numpy.frombuffer(
                                      tag_bytes, dtype=dtype
                                  ).copy()
                                  if len(tag_val) == 1:
                                      tag_val = tag_val[0]
                              except Exception:  # pragma: no cover
                                  pass
                      # Store data in dict
                      subdict = metadata.setdefault(model_name, Dict())
                      subdict[tag_name] = tag_val
                      # Next
                      more = lib.FreeImage_FindNextMetadata(
                          mdhandle, ctypes.byref(tag)
                      )
  
                  # Close search handle for current meta model
                  lib.FreeImage_FindCloseMetadata(mdhandle)
  
          # Done
          return metadata
  
imports: import os
  import sys
  import ctypes
  import threading
  import logging
  import numpy
  from ..core import get_remote_file, load_lib, Dict, resource_dirs, IS_PYPY, get_platform, InternetNotAllowedError, NeedDownloadError
label_desc: Use image node_id 5 for calling the FIBaseBitmap obj's underlying member method code with example usage: obj.get_meta_data() and returns: metadata