code: def ndarray_to_pil(arr, format_str=None, prefer_uint8=True):
      from PIL import Image
  
      if arr.ndim == 3:
          arr = image_as_uint(arr, bitdepth=8)
          mode = {3: "RGB", 4: "RGBA"}[arr.shape[2]]
  
      elif format_str in ["png", "PNG"]:
          mode = "I;16"
          mode_base = "I"
  
          if arr.dtype.kind == "f":
              arr = image_as_uint(arr)
  
          elif prefer_uint8 and arr.max() < 256 and arr.min() >= 0:
              arr = arr.astype(np.uint8)
              mode = mode_base = "L"
  
          else:
              arr = image_as_uint(arr, bitdepth=16)
  
      else:
          arr = image_as_uint(arr, bitdepth=8)
          mode = "L"
          mode_base = "L"
  
      if (
          mode == "I;16"
          and int(getattr(Image, "__version__", "0").split(".")[0]) < 6
      ):
          # Pillow < v6.0.0 has limited support for the "I;16" mode,
          # requiring us to fall back to this expensive workaround.
          # tobytes actually creates a copy of the image, which is costly.
          array_buffer = arr.tobytes()
          if arr.ndim == 2:
              im = Image.new(mode_base, arr.T.shape)
              im.frombytes(array_buffer, "raw", mode)
          else:
              image_shape = (arr.shape[1], arr.shape[0])
              im = Image.frombytes(mode, image_shape, array_buffer)
          return im
      else:
          return Image.fromarray(arr, mode)
  
imports: import logging
  import threading
  import numpy
  from ..core import Format, image_as_uint
  from ..core.request import URI_FILE, URI_BYTES
  from .pillowmulti import GIFFormat, TIFFFormat
label_desc: Use image node_id 5 for calling a global function with example usage: ndarray_to_pil(arr, format_str, prefer_uint8) and returns: im, Image