mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-04-29 05:23:41 +03:00
Merge branch 'main' into fix-padding
This commit is contained in:
commit
b3e847a164
17
.github/renovate.json
vendored
Normal file
17
.github/renovate.json
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"config:base"
|
||||||
|
],
|
||||||
|
"labels": [
|
||||||
|
"Dependency"
|
||||||
|
],
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"groupName": "github-actions",
|
||||||
|
"matchManagers": ["github-actions"],
|
||||||
|
"separateMajorMinor": "false"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"schedule": ["on the 3rd day of the month"]
|
||||||
|
}
|
|
@ -40,6 +40,7 @@ repos:
|
||||||
rev: v4.3.0
|
rev: v4.3.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-merge-conflict
|
- id: check-merge-conflict
|
||||||
|
- id: check-json
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
|
|
||||||
- repo: https://github.com/sphinx-contrib/sphinx-lint
|
- repo: https://github.com/sphinx-contrib/sphinx-lint
|
||||||
|
|
|
@ -25,6 +25,7 @@ exclude .coveragerc
|
||||||
exclude .editorconfig
|
exclude .editorconfig
|
||||||
exclude .readthedocs.yml
|
exclude .readthedocs.yml
|
||||||
exclude codecov.yml
|
exclude codecov.yml
|
||||||
|
exclude renovate.json
|
||||||
global-exclude .git*
|
global-exclude .git*
|
||||||
global-exclude *.pyc
|
global-exclude *.pyc
|
||||||
global-exclude *.so
|
global-exclude *.so
|
||||||
|
|
|
@ -74,6 +74,9 @@ As of 2019, Pillow development is
|
||||||
<a href="https://pypi.org/project/Pillow/"><img
|
<a href="https://pypi.org/project/Pillow/"><img
|
||||||
alt="Number of PyPI downloads"
|
alt="Number of PyPI downloads"
|
||||||
src="https://img.shields.io/pypi/dm/pillow.svg"></a>
|
src="https://img.shields.io/pypi/dm/pillow.svg"></a>
|
||||||
|
<a href="https://bestpractices.coreinfrastructure.org/projects/6331"><img
|
||||||
|
alt="OpenSSF Best Practices"
|
||||||
|
src="https://bestpractices.coreinfrastructure.org/projects/6331/badge"></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -1087,6 +1087,19 @@ def test_palette_save_P(tmp_path):
|
||||||
assert_image_equal(reloaded, im)
|
assert_image_equal(reloaded, im)
|
||||||
|
|
||||||
|
|
||||||
|
def test_palette_save_duplicate_entries(tmp_path):
|
||||||
|
im = Image.new("P", (1, 2))
|
||||||
|
im.putpixel((0, 1), 1)
|
||||||
|
|
||||||
|
im.putpalette((0, 0, 0, 0, 0, 0))
|
||||||
|
|
||||||
|
out = str(tmp_path / "temp.gif")
|
||||||
|
im.save(out, palette=[0, 0, 0, 0, 0, 0, 1, 1, 1])
|
||||||
|
|
||||||
|
with Image.open(out) as reloaded:
|
||||||
|
assert reloaded.convert("RGB").getpixel((0, 1)) == (0, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
def test_palette_save_all_P(tmp_path):
|
def test_palette_save_all_P(tmp_path):
|
||||||
frames = []
|
frames = []
|
||||||
colors = ((255, 0, 0), (0, 255, 0))
|
colors = ((255, 0, 0), (0, 255, 0))
|
||||||
|
|
|
@ -620,6 +620,7 @@ class TestImage:
|
||||||
|
|
||||||
im_remapped = im.remap_palette([1, 0])
|
im_remapped = im.remap_palette([1, 0])
|
||||||
assert im_remapped.info["transparency"] == 1
|
assert im_remapped.info["transparency"] == 1
|
||||||
|
assert len(im_remapped.getpalette()) == 6
|
||||||
|
|
||||||
# Test unused transparency
|
# Test unused transparency
|
||||||
im.info["transparency"] = 2
|
im.info["transparency"] = 2
|
||||||
|
|
|
@ -110,6 +110,16 @@ def test_contain(new_size):
|
||||||
assert new_im.size == (256, 256)
|
assert new_im.size == (256, 256)
|
||||||
|
|
||||||
|
|
||||||
|
def test_contain_round():
|
||||||
|
im = Image.new("1", (43, 63), 1)
|
||||||
|
new_im = ImageOps.contain(im, (5, 7))
|
||||||
|
assert new_im.width == 5
|
||||||
|
|
||||||
|
im = Image.new("1", (63, 43), 1)
|
||||||
|
new_im = ImageOps.contain(im, (7, 5))
|
||||||
|
assert new_im.height == 5
|
||||||
|
|
||||||
|
|
||||||
def test_pad():
|
def test_pad():
|
||||||
# Same ratio
|
# Same ratio
|
||||||
im = hopper()
|
im = hopper()
|
||||||
|
@ -130,6 +140,15 @@ def test_pad():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_pad_round():
|
||||||
|
im = Image.new("1", (1, 1), 1)
|
||||||
|
new_im = ImageOps.pad(im, (4, 1))
|
||||||
|
assert new_im.load()[2, 0] == 1
|
||||||
|
|
||||||
|
new_im = ImageOps.pad(im, (1, 4))
|
||||||
|
assert new_im.load()[0, 2] == 1
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ("P", "PA"))
|
@pytest.mark.parametrize("mode", ("P", "PA"))
|
||||||
def test_palette(mode):
|
def test_palette(mode):
|
||||||
im = hopper(mode)
|
im = hopper(mode)
|
||||||
|
|
|
@ -69,6 +69,10 @@ Pillow for enterprise is available via the Tidelift Subscription. `Learn more <h
|
||||||
:target: https://pypi.org/project/Pillow/
|
:target: https://pypi.org/project/Pillow/
|
||||||
:alt: Number of PyPI downloads
|
:alt: Number of PyPI downloads
|
||||||
|
|
||||||
|
.. image:: https://bestpractices.coreinfrastructure.org/projects/6331/badge
|
||||||
|
:target: https://bestpractices.coreinfrastructure.org/projects/6331
|
||||||
|
:alt: OpenSSF Best Practices
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
|
@ -519,9 +519,8 @@ def _normalize_palette(im, palette, info):
|
||||||
used_palette_colors = []
|
used_palette_colors = []
|
||||||
for i in range(0, len(source_palette), 3):
|
for i in range(0, len(source_palette), 3):
|
||||||
source_color = tuple(source_palette[i : i + 3])
|
source_color = tuple(source_palette[i : i + 3])
|
||||||
try:
|
index = im.palette.colors.get(source_color)
|
||||||
index = im.palette.colors[source_color]
|
if index in used_palette_colors:
|
||||||
except KeyError:
|
|
||||||
index = None
|
index = None
|
||||||
used_palette_colors.append(index)
|
used_palette_colors.append(index)
|
||||||
for i, index in enumerate(used_palette_colors):
|
for i, index in enumerate(used_palette_colors):
|
||||||
|
|
|
@ -1949,11 +1949,7 @@ class Image:
|
||||||
|
|
||||||
m_im = m_im.convert("L")
|
m_im = m_im.convert("L")
|
||||||
|
|
||||||
# Internally, we require 256 palette entries.
|
m_im.putpalette(palette_bytes, palette_mode)
|
||||||
new_palette_bytes = (
|
|
||||||
palette_bytes + ((256 * bands) - len(palette_bytes)) * b"\x00"
|
|
||||||
)
|
|
||||||
m_im.putpalette(new_palette_bytes, palette_mode)
|
|
||||||
m_im.palette = ImagePalette.ImagePalette(palette_mode, palette=palette_bytes)
|
m_im.palette = ImagePalette.ImagePalette(palette_mode, palette=palette_bytes)
|
||||||
|
|
||||||
if "transparency" in self.info:
|
if "transparency" in self.info:
|
||||||
|
|
|
@ -255,11 +255,11 @@ def contain(image, size, method=Image.Resampling.BICUBIC):
|
||||||
|
|
||||||
if im_ratio != dest_ratio:
|
if im_ratio != dest_ratio:
|
||||||
if im_ratio > dest_ratio:
|
if im_ratio > dest_ratio:
|
||||||
new_height = int(image.height / image.width * size[0])
|
new_height = round(image.height / image.width * size[0])
|
||||||
if new_height != size[1]:
|
if new_height != size[1]:
|
||||||
size = (size[0], new_height)
|
size = (size[0], new_height)
|
||||||
else:
|
else:
|
||||||
new_width = int(image.width / image.height * size[1])
|
new_width = round(image.width / image.height * size[1])
|
||||||
if new_width != size[0]:
|
if new_width != size[0]:
|
||||||
size = (new_width, size[1])
|
size = (new_width, size[1])
|
||||||
return image.resize(size, resample=method)
|
return image.resize(size, resample=method)
|
||||||
|
@ -294,10 +294,10 @@ def pad(image, size, method=Image.Resampling.BICUBIC, color=None, centering=(0.5
|
||||||
if resized.palette:
|
if resized.palette:
|
||||||
out.putpalette(resized.getpalette())
|
out.putpalette(resized.getpalette())
|
||||||
if resized.width != size[0]:
|
if resized.width != size[0]:
|
||||||
x = int((size[0] - resized.width) * max(0, min(centering[0], 1)))
|
x = round((size[0] - resized.width) * max(0, min(centering[0], 1)))
|
||||||
out.paste(resized, (x, 0))
|
out.paste(resized, (x, 0))
|
||||||
else:
|
else:
|
||||||
y = int((size[1] - resized.height) * max(0, min(centering[1], 1)))
|
y = round((size[1] - resized.height) * max(0, min(centering[1], 1)))
|
||||||
out.paste(resized, (0, y))
|
out.paste(resized, (0, y))
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user