File size: 1,680 Bytes
b2ffc9b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@author : Romain Graux
@date : 2023 April 25, 11:59:06
@last modified : 2023 September 19, 11:18:36
"""

import re
import imageio
import numpy as np
from collections import namedtuple

physical_metadata = namedtuple("physical_metadata", ["width", "height", "pixel_width", "pixel_height", "unit"])

def extract_physical_metadata(image_path : str, strict:bool=True) -> physical_metadata:
    """
    Extracts the physical metadata of an image (only tiff for now)
    """
    with open(image_path, "rb") as f:
        data = f.read()
        reader = imageio.get_reader(data, format=".tif")
        metadata = reader.get_meta_data()

    if strict and not metadata['is_imagej']:
        for key, value in metadata.items():
            if key.startswith("is_") and value == True: # Force bool to be True, because it can also pass the condition while being an random object
                raise ValueError(f"The image is not TIFF image, but it seems to be a {key[3:]} image")
        raise ValueError("Impossible to extract metadata from the image (ImageJ)")
    h, w = reader.get_next_data().shape
    ipw, iph, _ = metadata['resolution']
    result = re.search(r"unit=(.+)", metadata['description'])
    if strict and not result:
        raise ValueError(f"No scale unit found in the image description : {metadata['description']}")
    unit = result and result.group(1)
    return physical_metadata(w, h, 1. / ipw, 1. / iph, unit)

def tiff_to_png(image, inplace=True):
    img = image if inplace else image.copy()
    if np.array(img.getdata()).max() <= 1:
        img = img.point(lambda p: p * 255)
    return img.convert("RGB")