Last active
March 22, 2019 14:36
-
-
Save scossu/77c05daac125e8250f916b0ddc8dd50a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# | |
# Convert TIFF to a Pyramidal TIFF using PyVips. | |
# Usage: tiff_to_ptiff.py <input image path> <output image path> | |
import logging | |
import sys | |
from io import BytesIO | |
from os import path | |
import pyvips | |
from pyvips.enums import Interpretation as chmode, Intent | |
SRGB_PROFILE_FPATH = path.join(gcis.basedir, "resources", "sRGB2014.icc") | |
GRAY_PROFILE_FPATH = path.join( | |
gcis.basedir, "resources", "generic_gray_gamma_2.2.icc" | |
) | |
logger = logging.getLogger(__name__) | |
def tiff_to_ptiff(data, out_path=None, auto_flatten=False): | |
""" | |
Convert a TIFF image to a pyramidal TIFF using pyvips and tiffcp. | |
:param BytesIO data: Streaming buffer to read from. | |
:param str out_path: Path to write to. If omitted, a BytesIO object is | |
returned. | |
:param bool auto_flatten: If set to True, when an image with alpha is | |
encountered, the channel will be discarded and the image flattened. | |
If False (the default), an exception is raised in order to allow | |
manual inspection and correction of the image. | |
:rtype: BytesIO or None | |
:return: Byte buffer with encoded TIFF image contents, if ``out_path`` was | |
not set, otherwise ``None``. | |
""" | |
pyvips.cache_set_max(0) | |
img = pyvips.Image.new_from_buffer(data.read(), "", access="sequential") | |
channels = img.interpretation | |
if channels not in (chmode.SRGB, chmode.RGB, chmode.B_W): | |
raise ValueError(f"Color mode {channels} is not supported.") | |
# Since only RGB and gray are supported, 4 bands means RGBA, 2 bands | |
# means Gray + A. | |
if img.bands == 4 or img.bands == 2: | |
if auto_flatten: | |
logger.info("Removing alpha channel.") | |
img = img.flatten() | |
else: | |
raise ValueError( | |
"Alpha channel detected. Not trying to flatten automatically." | |
) | |
# Set the right ICC profile unconditionally. | |
logger.info("Setting ICC profile.") | |
profile_fpath = ( | |
GRAY_PROFILE_FPATH if channels == chmode.B_W else SRGB_PROFILE_FPATH | |
) | |
# with open(profile_fpath) as fh: | |
# img.set('icc-profile-data', fh.read()) | |
img = img.icc_transform(profile_fpath, intent=Intent.PERCEPTUAL) | |
kw = { | |
"compression": "jpeg", | |
"Q": 90, | |
"profile": profile_fpath, | |
"tile": True, | |
"tile_width": 256, | |
"tile_height": 256, | |
"pyramid": True, | |
"bigtiff": True, | |
#"region_shrink": "average", | |
} | |
if out_path: | |
img.tiffsave(out_path, **kw) | |
else: | |
return BytesIO(img.tiffsave_buffer(**kw)) | |
if __name__ = "__main__": | |
with open(sys.argv[0], 'rb') as fh: | |
tiff_to_ptiff(fh, sys.argv[1]) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment