mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-27 09:44:31 +03:00
Merge branch 'master' into reduce-in-resize
This commit is contained in:
commit
222c2f6978
1
.github/workflows/test-docker.yml
vendored
1
.github/workflows/test-docker.yml
vendored
|
@ -17,6 +17,7 @@ jobs:
|
||||||
debian-10-buster-x86,
|
debian-10-buster-x86,
|
||||||
centos-6-amd64,
|
centos-6-amd64,
|
||||||
centos-7-amd64,
|
centos-7-amd64,
|
||||||
|
centos-8-amd64,
|
||||||
amazon-1-amd64,
|
amazon-1-amd64,
|
||||||
amazon-2-amd64,
|
amazon-2-amd64,
|
||||||
fedora-30-amd64,
|
fedora-30-amd64,
|
||||||
|
|
|
@ -40,6 +40,7 @@ matrix:
|
||||||
- env: DOCKER="debian-10-buster-x86" DOCKER_TAG="master"
|
- env: DOCKER="debian-10-buster-x86" DOCKER_TAG="master"
|
||||||
- env: DOCKER="centos-6-amd64" DOCKER_TAG="master"
|
- env: DOCKER="centos-6-amd64" DOCKER_TAG="master"
|
||||||
- env: DOCKER="centos-7-amd64" DOCKER_TAG="master"
|
- env: DOCKER="centos-7-amd64" DOCKER_TAG="master"
|
||||||
|
- env: DOCKER="centos-8-amd64" DOCKER_TAG="master"
|
||||||
- env: DOCKER="amazon-1-amd64" DOCKER_TAG="master"
|
- env: DOCKER="amazon-1-amd64" DOCKER_TAG="master"
|
||||||
- env: DOCKER="amazon-2-amd64" DOCKER_TAG="master"
|
- env: DOCKER="amazon-2-amd64" DOCKER_TAG="master"
|
||||||
- env: DOCKER="fedora-30-amd64" DOCKER_TAG="master"
|
- env: DOCKER="fedora-30-amd64" DOCKER_TAG="master"
|
||||||
|
|
|
@ -5,6 +5,12 @@ Changelog (Pillow)
|
||||||
7.0.0 (unreleased)
|
7.0.0 (unreleased)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
- Raise ValueError for io.StringIO in Image.open #4302
|
||||||
|
[radarhere, hugovk]
|
||||||
|
|
||||||
|
- Fix thumbnail geometry when DCT scaling is used #4231
|
||||||
|
[homm, radarhere]
|
||||||
|
|
||||||
- Use default DPI when exif provides invalid x_resolution #4147
|
- Use default DPI when exif provides invalid x_resolution #4147
|
||||||
[beipang2, radarhere]
|
[beipang2, radarhere]
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import io
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -91,6 +92,9 @@ class TestImage(PillowTestCase):
|
||||||
def test_bad_mode(self):
|
def test_bad_mode(self):
|
||||||
self.assertRaises(ValueError, Image.open, "filename", "bad mode")
|
self.assertRaises(ValueError, Image.open, "filename", "bad mode")
|
||||||
|
|
||||||
|
def test_stringio(self):
|
||||||
|
self.assertRaises(ValueError, Image.open, io.StringIO())
|
||||||
|
|
||||||
def test_pathlib(self):
|
def test_pathlib(self):
|
||||||
from PIL.Image import Path
|
from PIL.Image import Path
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ class TestImageReduce(PillowTestCase):
|
||||||
# rotate previous image
|
# rotate previous image
|
||||||
band = bands[-1].transpose(Image.ROTATE_90)
|
band = bands[-1].transpose(Image.ROTATE_90)
|
||||||
bands.append(band)
|
bands.append(band)
|
||||||
# Correct alpha channel to exclude completely transparent pixels.
|
# Correct alpha channel by transforming completely transparent pixels.
|
||||||
# Low alpha values also emphasize error after alpha multiplication.
|
# Low alpha values also emphasize error after alpha multiplication.
|
||||||
if mode.endswith("A"):
|
if mode.endswith("A"):
|
||||||
bands[-1] = bands[-1].point(lambda x: int(85 + x / 1.5))
|
bands[-1] = bands[-1].point(lambda x: int(85 + x / 1.5))
|
||||||
|
@ -102,7 +102,7 @@ class TestImageReduce(PillowTestCase):
|
||||||
else:
|
else:
|
||||||
assert len(mode_info.bands) == 1
|
assert len(mode_info.bands) == 1
|
||||||
im = self.gradients_image.convert(mode)
|
im = self.gradients_image.convert(mode)
|
||||||
# change the height to make a not square image
|
# change the height to make a not-square image
|
||||||
return im.crop((0, 0, im.width, im.height - 5))
|
return im.crop((0, 0, im.width, im.height - 5))
|
||||||
|
|
||||||
def compare_reduce_with_box(self, im, factor):
|
def compare_reduce_with_box(self, im, factor):
|
||||||
|
@ -196,7 +196,7 @@ class TestImageReduce(PillowTestCase):
|
||||||
for factor in self.remarkable_factors:
|
for factor in self.remarkable_factors:
|
||||||
self.compare_reduce_with_reference(im, factor, 0.8, 5)
|
self.compare_reduce_with_reference(im, factor, 0.8, 5)
|
||||||
|
|
||||||
# With opaque alpha, error should be way smaller
|
# With opaque alpha, an error should be way smaller.
|
||||||
im.putalpha(Image.new("L", im.size, 255))
|
im.putalpha(Image.new("L", im.size, 255))
|
||||||
for factor in self.remarkable_factors:
|
for factor in self.remarkable_factors:
|
||||||
self.compare_reduce_with_reference(im, factor)
|
self.compare_reduce_with_reference(im, factor)
|
||||||
|
@ -219,7 +219,7 @@ class TestImageReduce(PillowTestCase):
|
||||||
for factor in self.remarkable_factors:
|
for factor in self.remarkable_factors:
|
||||||
self.compare_reduce_with_reference(im, factor, 0.8, 5)
|
self.compare_reduce_with_reference(im, factor, 0.8, 5)
|
||||||
|
|
||||||
# With opaque alpha, error should be way smaller
|
# With opaque alpha, an error should be way smaller.
|
||||||
im.putalpha(Image.new("L", im.size, 255))
|
im.putalpha(Image.new("L", im.size, 255))
|
||||||
for factor in self.remarkable_factors:
|
for factor in self.remarkable_factors:
|
||||||
self.compare_reduce_with_reference(im, factor)
|
self.compare_reduce_with_reference(im, factor)
|
||||||
|
|
|
@ -377,7 +377,7 @@ class TestLibUnpack(PillowTestCase):
|
||||||
self.assert_unpack(
|
self.assert_unpack(
|
||||||
"RGBA",
|
"RGBA",
|
||||||
"RGBa;16L",
|
"RGBa;16L",
|
||||||
b"\x88\x01\x88\x02\x88\x03\x88\x00" b"\x88\x10\x88\x20\x88\x30\x88\xff",
|
b"\x88\x01\x88\x02\x88\x03\x88\x00\x88\x10\x88\x20\x88\x30\x88\xff",
|
||||||
(0, 0, 0, 0),
|
(0, 0, 0, 0),
|
||||||
(16, 32, 48, 255),
|
(16, 32, 48, 255),
|
||||||
)
|
)
|
||||||
|
@ -392,7 +392,7 @@ class TestLibUnpack(PillowTestCase):
|
||||||
self.assert_unpack(
|
self.assert_unpack(
|
||||||
"RGBA",
|
"RGBA",
|
||||||
"RGBa;16B",
|
"RGBa;16B",
|
||||||
b"\x01\x88\x02\x88\x03\x88\x00\x88" b"\x10\x88\x20\x88\x30\x88\xff\x88",
|
b"\x01\x88\x02\x88\x03\x88\x00\x88\x10\x88\x20\x88\x30\x88\xff\x88",
|
||||||
(0, 0, 0, 0),
|
(0, 0, 0, 0),
|
||||||
(16, 32, 48, 255),
|
(16, 32, 48, 255),
|
||||||
)
|
)
|
||||||
|
|
|
@ -51,6 +51,11 @@ jobs:
|
||||||
docker: 'centos-7-amd64'
|
docker: 'centos-7-amd64'
|
||||||
name: 'centos_7_amd64'
|
name: 'centos_7_amd64'
|
||||||
|
|
||||||
|
- template: .azure-pipelines/jobs/test-docker.yml
|
||||||
|
parameters:
|
||||||
|
docker: 'centos-8-amd64'
|
||||||
|
name: 'centos_8_amd64'
|
||||||
|
|
||||||
- template: .azure-pipelines/jobs/test-docker.yml
|
- template: .azure-pipelines/jobs/test-docker.yml
|
||||||
parameters:
|
parameters:
|
||||||
docker: 'amazon-1-amd64'
|
docker: 'amazon-1-amd64'
|
||||||
|
|
|
@ -400,6 +400,8 @@ These platforms are built and tested for every change.
|
||||||
+----------------------------------+--------------------------+-----------------------+
|
+----------------------------------+--------------------------+-----------------------+
|
||||||
| CentOS 7 | 3.6 |x86-64 |
|
| CentOS 7 | 3.6 |x86-64 |
|
||||||
+----------------------------------+--------------------------+-----------------------+
|
+----------------------------------+--------------------------+-----------------------+
|
||||||
|
| CentOS 8 | 3.6 |x86-64 |
|
||||||
|
+----------------------------------+--------------------------+-----------------------+
|
||||||
| Debian 9 Stretch | 3.5 |x86 |
|
| Debian 9 Stretch | 3.5 |x86 |
|
||||||
+----------------------------------+--------------------------+-----------------------+
|
+----------------------------------+--------------------------+-----------------------+
|
||||||
| Debian 10 Buster | 3.7 |x86 |
|
| Debian 10 Buster | 3.7 |x86 |
|
||||||
|
|
|
@ -1797,9 +1797,9 @@ class Image:
|
||||||
If the image has mode "1" or "P", it is
|
If the image has mode "1" or "P", it is
|
||||||
always set to :py:attr:`PIL.Image.NEAREST`.
|
always set to :py:attr:`PIL.Image.NEAREST`.
|
||||||
See: :ref:`concept-filters`.
|
See: :ref:`concept-filters`.
|
||||||
:param box: An optional 4-tuple of floats giving the region
|
:param box: An optional 4-tuple of floats providing
|
||||||
of the source image which should be scaled.
|
the source image region to be scaled.
|
||||||
The values should be within (0, 0, width, height) rectangle.
|
The values must be within (0, 0, width, height) rectangle.
|
||||||
If omitted or None, the entire source is used.
|
If omitted or None, the entire source is used.
|
||||||
:param reducing_gap: Apply optimization by resizing the image
|
:param reducing_gap: Apply optimization by resizing the image
|
||||||
in two steps. First, reducing the image in integer times
|
in two steps. First, reducing the image in integer times
|
||||||
|
@ -1874,15 +1874,15 @@ class Image:
|
||||||
|
|
||||||
def reduce(self, factor, box=None):
|
def reduce(self, factor, box=None):
|
||||||
"""
|
"""
|
||||||
Returns reduced in `factor` times copy of the image.
|
Returns a copy of the image reduced by `factor` times.
|
||||||
If the size of the image is not dividable by the `factor`,
|
If the size of the image is not dividable by the `factor`,
|
||||||
the resulting size will be rounded up.
|
the resulting size will be rounded up.
|
||||||
|
|
||||||
:param factor: A greater than 0 integer or tuple of two integers
|
:param factor: A greater than 0 integer or tuple of two integers
|
||||||
for width and height separately.
|
for width and height separately.
|
||||||
:param box: An optional 4-tuple of ints giving the region
|
:param box: An optional 4-tuple of ints providing
|
||||||
of the source image which should be reduced.
|
the source image region to be reduced.
|
||||||
The values should be within (0, 0, width, height) rectangle.
|
The values must be within (0, 0, width, height) rectangle.
|
||||||
If omitted or None, the entire source is used.
|
If omitted or None, the entire source is used.
|
||||||
"""
|
"""
|
||||||
if not isinstance(factor, (list, tuple)):
|
if not isinstance(factor, (list, tuple)):
|
||||||
|
@ -2783,12 +2783,20 @@ def open(fp, mode="r"):
|
||||||
and be opened in binary mode.
|
and be opened in binary mode.
|
||||||
:param mode: The mode. If given, this argument must be "r".
|
:param mode: The mode. If given, this argument must be "r".
|
||||||
:returns: An :py:class:`~PIL.Image.Image` object.
|
:returns: An :py:class:`~PIL.Image.Image` object.
|
||||||
:exception IOError: If the file cannot be found, or the image cannot be
|
:exception FileNotFoundError: If the file cannot be found.
|
||||||
opened and identified.
|
:exception PIL.UnidentifiedImageError: If the image cannot be opened and
|
||||||
|
identified.
|
||||||
|
:exception ValueError: If the ``mode`` is not "r", or if a ``StringIO``
|
||||||
|
instance is used for ``fp``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if mode != "r":
|
if mode != "r":
|
||||||
raise ValueError("bad mode %r" % mode)
|
raise ValueError("bad mode %r" % mode)
|
||||||
|
elif isinstance(fp, io.StringIO):
|
||||||
|
raise ValueError(
|
||||||
|
"StringIO cannot be used to open an image. "
|
||||||
|
"Binary data must be used instead."
|
||||||
|
)
|
||||||
|
|
||||||
exclusive_fp = False
|
exclusive_fp = False
|
||||||
filename = ""
|
filename = ""
|
||||||
|
|
|
@ -882,7 +882,6 @@ def _save(im, fp, filename, chunk=putchunk):
|
||||||
b"\x01",
|
b"\x01",
|
||||||
)
|
)
|
||||||
|
|
||||||
info = im.encoderinfo.get("pnginfo")
|
|
||||||
if info:
|
if info:
|
||||||
chunks = [b"bKGD", b"hIST"]
|
chunks = [b"bKGD", b"hIST"]
|
||||||
for cid, data in info.chunks:
|
for cid, data in info.chunks:
|
||||||
|
|
|
@ -225,8 +225,8 @@ set DefaultPlatformToolset=v100
|
||||||
if bit == 64:
|
if bit == 64:
|
||||||
script += (
|
script += (
|
||||||
r"copy /Y /B "
|
r"copy /Y /B "
|
||||||
+ r'"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib\x64\*.Lib" '
|
r'"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib\x64\*.Lib" '
|
||||||
+ r"%%FREETYPE%%\builds\windows\vc2010"
|
r"%%FREETYPE%%\builds\windows\vc2010"
|
||||||
)
|
)
|
||||||
properties += r" /p:_IsNativeEnvironment=false"
|
properties += r" /p:_IsNativeEnvironment=false"
|
||||||
script += (
|
script += (
|
||||||
|
|
Loading…
Reference in New Issue
Block a user