mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-13 18:56:17 +03:00
Merge pull request #5655 from radarhere/whiteiszero
Allow saving 1 and L mode TIFF with PhotometricInterpretation 0
This commit is contained in:
commit
2d01f7d022
|
@ -447,6 +447,15 @@ class TestFileTiff:
|
|||
im.seek(1)
|
||||
assert im.getexif()[273] == (1408, 1907)
|
||||
|
||||
@pytest.mark.parametrize("mode", ("1", "L"))
|
||||
def test_photometric(self, mode, tmp_path):
|
||||
filename = str(tmp_path / "temp.tif")
|
||||
im = hopper(mode)
|
||||
im.save(filename, tiffinfo={262: 0})
|
||||
with Image.open(filename) as reloaded:
|
||||
assert reloaded.tag_v2[262] == 0
|
||||
assert_image_equal(im, reloaded)
|
||||
|
||||
def test_seek(self):
|
||||
filename = "Tests/images/pil136.tiff"
|
||||
with Image.open(filename) as im:
|
||||
|
|
|
@ -48,7 +48,7 @@ from collections.abc import MutableMapping
|
|||
from fractions import Fraction
|
||||
from numbers import Number, Rational
|
||||
|
||||
from . import Image, ImageFile, ImagePalette, TiffTags
|
||||
from . import Image, ImageFile, ImageOps, ImagePalette, TiffTags
|
||||
from ._binary import o8
|
||||
from .TiffTags import TYPES
|
||||
|
||||
|
@ -1487,7 +1487,9 @@ def _save(im, fp, filename):
|
|||
|
||||
ifd = ImageFileDirectory_v2(prefix=prefix)
|
||||
|
||||
compression = im.encoderinfo.get("compression", im.info.get("compression"))
|
||||
encoderinfo = im.encoderinfo
|
||||
encoderconfig = im.encoderconfig
|
||||
compression = encoderinfo.get("compression", im.info.get("compression"))
|
||||
if compression is None:
|
||||
compression = "raw"
|
||||
elif compression == "tiff_jpeg":
|
||||
|
@ -1505,7 +1507,7 @@ def _save(im, fp, filename):
|
|||
ifd[IMAGELENGTH] = im.size[1]
|
||||
|
||||
# write any arbitrary tags passed in as an ImageFileDirectory
|
||||
info = im.encoderinfo.get("tiffinfo", {})
|
||||
info = encoderinfo.get("tiffinfo", {})
|
||||
logger.debug("Tiffinfo Keys: %s" % list(info))
|
||||
if isinstance(info, ImageFileDirectory_v1):
|
||||
info = info.to_v2()
|
||||
|
@ -1534,7 +1536,7 @@ def _save(im, fp, filename):
|
|||
|
||||
# preserve ICC profile (should also work when saving other formats
|
||||
# which support profiles as TIFF) -- 2008-06-06 Florian Hoech
|
||||
icc = im.encoderinfo.get("icc_profile", im.info.get("icc_profile"))
|
||||
icc = encoderinfo.get("icc_profile", im.info.get("icc_profile"))
|
||||
if icc:
|
||||
ifd[ICCPROFILE] = icc
|
||||
|
||||
|
@ -1550,10 +1552,10 @@ def _save(im, fp, filename):
|
|||
(ARTIST, "artist"),
|
||||
(COPYRIGHT, "copyright"),
|
||||
]:
|
||||
if name in im.encoderinfo:
|
||||
ifd[key] = im.encoderinfo[name]
|
||||
if name in encoderinfo:
|
||||
ifd[key] = encoderinfo[name]
|
||||
|
||||
dpi = im.encoderinfo.get("dpi")
|
||||
dpi = encoderinfo.get("dpi")
|
||||
if dpi:
|
||||
ifd[RESOLUTION_UNIT] = 2
|
||||
ifd[X_RESOLUTION] = dpi[0]
|
||||
|
@ -1568,7 +1570,18 @@ def _save(im, fp, filename):
|
|||
if format != 1:
|
||||
ifd[SAMPLEFORMAT] = format
|
||||
|
||||
if PHOTOMETRIC_INTERPRETATION not in ifd:
|
||||
ifd[PHOTOMETRIC_INTERPRETATION] = photo
|
||||
elif im.mode in ("1", "L") and ifd[PHOTOMETRIC_INTERPRETATION] == 0:
|
||||
if im.mode == "1":
|
||||
inverted_im = im.copy()
|
||||
px = inverted_im.load()
|
||||
for y in range(inverted_im.height):
|
||||
for x in range(inverted_im.width):
|
||||
px[x, y] = 0 if px[x, y] == 255 else 255
|
||||
im = inverted_im
|
||||
else:
|
||||
im = ImageOps.invert(im)
|
||||
|
||||
if im.mode in ["P", "PA"]:
|
||||
lut = im.im.getpalette("RGB", "RGB;L")
|
||||
|
@ -1605,8 +1618,8 @@ def _save(im, fp, filename):
|
|||
ifd.setdefault(tag, value)
|
||||
|
||||
if libtiff:
|
||||
if "quality" in im.encoderinfo:
|
||||
quality = im.encoderinfo["quality"]
|
||||
if "quality" in encoderinfo:
|
||||
quality = encoderinfo["quality"]
|
||||
if not isinstance(quality, int) or quality < 0 or quality > 100:
|
||||
raise ValueError("Invalid quality setting")
|
||||
if compression != "jpeg":
|
||||
|
@ -1695,7 +1708,7 @@ def _save(im, fp, filename):
|
|||
tags = list(atts.items())
|
||||
tags.sort()
|
||||
a = (rawmode, compression, _fp, filename, tags, types)
|
||||
e = Image._getencoder(im.mode, "libtiff", a, im.encoderconfig)
|
||||
e = Image._getencoder(im.mode, "libtiff", a, encoderconfig)
|
||||
e.setimage(im.im, (0, 0) + im.size)
|
||||
while True:
|
||||
# undone, change to self.decodermaxblock:
|
||||
|
@ -1715,7 +1728,7 @@ def _save(im, fp, filename):
|
|||
)
|
||||
|
||||
# -- helper for multi-page save --
|
||||
if "_debug_multipage" in im.encoderinfo:
|
||||
if "_debug_multipage" in encoderinfo:
|
||||
# just to access o32 and o16 (using correct byte order)
|
||||
im._debug_multipage = ifd
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user