diff --git a/pyproject.toml b/pyproject.toml index 0a2f16570dffce2ca7cf820d74f08f675ec2a5f9..178a43f462c0ea35cfec039eb241b30c4302f0fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,6 +61,7 @@ qcodes = [ ] image = [ "moviepy", + "tifffile[all]" ] doc = [ "sphinx", diff --git a/qutil/image.py b/qutil/image.py index 2f9daeac988ce8e9d002569c93bcc9c3fe4b0d06..d362715951d66ec8999deb6d331857b7af31d805 100644 --- a/qutil/image.py +++ b/qutil/image.py @@ -3,12 +3,9 @@ import pathlib from typing import Optional, Union, Literal import numpy as np -from PIL import Image, ImageSequence +import tifffile from moviepy.editor import ImageSequenceClip -from qutil.misc import filter_warnings -from qutil.itertools import ignore_exceptions - try: from numpy.typing import NDArray except ImportError: @@ -17,15 +14,6 @@ except ImportError: _pathT = Union[str, os.PathLike] -def read_tiff(path: _pathT) -> NDArray: - """Read a (multipage) .tif image and return it as an array.""" - # Catch the following error for files generated by the Thorlabs Camera: - # OSError: Corrupt EXIF data. Expecting to read 2 bytes but only got 0. - with Image.open(path) as im, filter_warnings('error', UserWarning): - frames = list(ignore_exceptions(ImageSequence.Iterator(im), UserWarning)) - return np.array(frames) - - def convert_tiff(file: _pathT, fps: float, format: str = '.mp4', threads: Optional[int] = None, out: Optional[_pathT] = None, logger: Optional[Literal['bar']] = None): """Converts a multipage .tif file to `format` and writes it to disk. @@ -63,7 +51,11 @@ def convert_tiff(file: _pathT, fps: float, format: str = '.mp4', threads: Option threads=os.cpu_count()) """ - file = pathlib.Path(file).with_suffix('.tif') - clip = ImageSequenceClip(read_tiff(file), fps=fps) - clip.write_videofile((out or file).with_suffix(format), fps, audio=False, threads=threads, + in_name = pathlib.Path(file).with_suffix('.tif') + out_name = (out or in_name).with_suffix(format) + + data = tifffile.imread(str(in_name)) + clip = ImageSequenceClip(list(data), fps=fps) + + clip.write_videofile(out_name, fps, audio=False, threads=threads, logger=logger)