import base64 import mimetypes from io import BytesIO from PIL import Image, ImageFile import pydicom import sys import glob import itertools try: from .pydicom_PIL import get_PIL_image except: from pydicom_PIL import get_PIL_image def image_as_base64(image_file): """ :param `image_file` for the complete path of image. :param `format` is format for image, eg: `png` or `jpg`. """ # if not os.path.isfile(image_file): # return None encoded_string = "" # with open(image_file, 'rb') as img_f: # encoded_string = base64.b64encode(img_f.read()) encoded_string = base64.b64encode(image_file.file.read()) mimetype, enc = mimetypes.guess_type(image_file.path) # Treat unknown files as dicom if None == mimetype: return "data:application/dicom;base64,{}".format(encoded_string.decode("utf-8")) if "dicom" in mimetype or "octet-stream" in mimetype: return "data:{};base64,{}".format(mimetype, encoded_string.decode("utf-8")) return "data:image/{};base64,{}".format(mimetype, encoded_string.decode("utf-8")) def pil_dicom_image(source, exif_orientation=True, **options): """ Try to open the source file directly using PIL, ignoring any errors. exif_orientation If EXIF orientation data is present, perform any required reorientation before passing the data along the processing pipeline. """ # Use a BytesIO wrapper because if the source is an incomplete file like # object, PIL may have problems with it. For example, some image types # require tell and seek methods that are not present on all storage # File objects. #if not source: # return #source = BytesIO(source.read()) # open file with pydicom ds = pydicom.read_file(source) # return the image file return get_PIL_image(ds) #with Image.open(source) as image: # # Fully load the image now to catch any problems with the image contents. # try: # ImageFile.LOAD_TRUNCATED_IMAGES = True # image.load() # finally: # ImageFile.LOAD_TRUNCATED_IMAGES = False #if exif_orientation: # image = utils.exif_orientation(image) def show_PIL(dataset): """Display an image using the Python Imaging Library (PIL)""" im = get_PIL_image(dataset) im.show() def get_dicom_order(path): # load the DICOM files files = [] for fname in glob.glob(path, recursive=False): print("loading: {}".format(fname)) files.append((fname, pydicom.dcmread(fname))) print("file count: {}".format(len(files))) # skip files with no SliceLocation (eg scout views) slices = [] map = {} skipcount = 0 for fname, f in files: print(dir(f)) print(fname) if hasattr(f, 'SliceLocation'): slices.append(f) map[f.SliceLocation] = fname else: skipcount = skipcount + 1 print("skipped, no SliceLocation: {}".format(skipcount)) # ensure they are in the correct order slices = sorted(slices, key=lambda s: s.SliceLocation) #print(slices) for i in slices: print(map[i.SliceLocation]) #get_dicom_order("/home/ross/Downloads/DICOM HEAD/STD4/SER1/*.dcm") def pretty_print_dicom(dataset, indent=0): l = print_dicom(dataset, indent) print(l) return "".join(l) def print_dicom(dataset, indent=0): """Go through all items in the dataset and print them with custom format Modelled after Dataset._pretty_str() """ dont_print = ['Pixel Data', 'File Meta Information Version'] indent_string = "---" * indent next_indent_string = "---" * (indent + 1) l = [] for data_element in dataset: if data_element.VR == "SQ": # a sequence l.append(f"{indent_string}{data_element.name}") for sequence_item in data_element.value: l.append(print_dicom(sequence_item, indent + 1)) l.append(next_indent_string + "---------") else: if data_element.name in dont_print: l.append("""item not printed -- in the "don't print" list""") else: repr_value = repr(data_element.value) if len(repr_value) > 50: repr_value = repr_value[:50] + "..." l.append("{0:s} {1:s} = {2:s}".format(indent_string, data_element.name, repr_value)) return "\n
".join(l)