Merge remote-tracking branch 'upstream/master' into anchor

This commit is contained in:
nulano 2020-07-22 23:42:11 +02:00
commit a4ca3ca560
136 changed files with 1853 additions and 1419 deletions

View File

@ -14,7 +14,7 @@ environment:
matrix: matrix:
- PYTHON: C:/Python38 - PYTHON: C:/Python38
ARCHITECTURE: x86 ARCHITECTURE: x86
- PYTHON: C:/Python35-x64 - PYTHON: C:/Python36-x64
ARCHITECTURE: x64 ARCHITECTURE: x64

View File

@ -30,6 +30,7 @@ pip install -U pytest-cov
pip install pyroma pip install pyroma
pip install test-image-results pip install test-image-results
pip install numpy pip install numpy
if [ "$TRAVIS_PYTHON_VERSION" == "3.9-dev" ]; then pip install setuptools==47.3.1 ; fi
if [[ $TRAVIS_PYTHON_VERSION == 3.* ]]; then if [[ $TRAVIS_PYTHON_VERSION == 3.* ]]; then
# arm64, ppc64le, s390x CPUs: # arm64, ppc64le, s390x CPUs:
# "ERROR: Could not find a version that satisfies the requirement pyqt5" # "ERROR: Could not find a version that satisfies the requirement pyqt5"

View File

@ -6,17 +6,14 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8"]
name: Python ${{ matrix.python-version }} name: Lint
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: pip cache - name: pip cache
uses: actions/cache@v1 uses: actions/cache@v2
with: with:
path: ~/.cache/pip path: ~/.cache/pip
key: lint-pip-${{ hashFiles('**/setup.py') }} key: lint-pip-${{ hashFiles('**/setup.py') }}
@ -24,26 +21,28 @@ jobs:
lint-pip- lint-pip-
- name: pre-commit cache - name: pre-commit cache
uses: actions/cache@v1 uses: actions/cache@v2
with: with:
path: ~/.cache/pre-commit path: ~/.cache/pre-commit
key: lint-pre-commit-${{ hashFiles('**/.pre-commit-config.yaml') }} key: lint-pre-commit-${{ hashFiles('**/.pre-commit-config.yaml') }}
restore-keys: | restore-keys: |
lint-pre-commit- lint-pre-commit-
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python
uses: actions/setup-python@v1 uses: actions/setup-python@v2
with: with:
python-version: ${{ matrix.python-version }} python-version: 3.8
- name: Build system information - name: Build system information
run: python .github/workflows/system-info.py run: python .github/workflows/system-info.py
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install --upgrade pip python -m pip install -U pip
python -m pip install --upgrade tox python -m pip install -U tox
- name: Lint - name: Lint
run: tox -e lint run: tox -e lint
env:
PRE_COMMIT_COLOR: always

View File

@ -12,10 +12,8 @@ jobs:
docker: [ docker: [
alpine, alpine,
arch, arch,
ubuntu-16.04-xenial-amd64,
ubuntu-18.04-bionic-amd64, ubuntu-18.04-bionic-amd64,
ubuntu-20.04-focal-amd64, ubuntu-20.04-focal-amd64,
debian-9-stretch-x86,
debian-10-buster-x86, debian-10-buster-x86,
centos-6-amd64, centos-6-amd64,
centos-7-amd64, centos-7-amd64,

View File

@ -8,7 +8,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
python-version: ["3.5", "3.6", "3.7", "3.8", "pypy3"] python-version: ["3.6", "3.7", "3.8", "3.9-dev", "pypy3"]
architecture: ["x86", "x64"] architecture: ["x86", "x64"]
include: include:
- architecture: "x86" - architecture: "x86"
@ -36,7 +36,7 @@ jobs:
path: winbuild\depends path: winbuild\depends
- name: Cache pip - name: Cache pip
uses: actions/cache@v1 uses: actions/cache@v2
with: with:
path: ~\AppData\Local\pip\Cache path: ~\AppData\Local\pip\Cache
key: key:
@ -47,7 +47,7 @@ jobs:
# sets env: pythonLocation # sets env: pythonLocation
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v1 uses: actions/setup-python@v2
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.architecture }} architecture: ${{ matrix.architecture }}
@ -128,7 +128,7 @@ jobs:
shell: pwsh shell: pwsh
- name: Upload errors - name: Upload errors
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v2
if: failure() if: failure()
with: with:
name: errors name: errors

View File

@ -14,16 +14,16 @@ jobs:
] ]
python-version: [ python-version: [
"pypy3", "pypy3",
"3.9-dev",
"3.8", "3.8",
"3.7", "3.7",
"3.6", "3.6",
"3.5",
] ]
include: include:
- python-version: "3.5"
env: PYTHONOPTIMIZE=2
- python-version: "3.6" - python-version: "3.6"
env: PYTHONOPTIMIZE=1 env: PYTHONOPTIMIZE=1
- python-version: "3.7"
env: PYTHONOPTIMIZE=2
# Include new variables for Codecov # Include new variables for Codecov
- os: ubuntu-latest - os: ubuntu-latest
codecov-flag: GHA_Ubuntu codecov-flag: GHA_Ubuntu
@ -36,31 +36,25 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Ubuntu cache
uses: actions/cache@v1
if: startsWith(matrix.os, 'ubuntu')
with:
path: ~/.cache/pip
key:
${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('**/.ci/*.sh') }}
restore-keys: |
${{ matrix.os }}-${{ matrix.python-version }}-
- name: macOS cache
uses: actions/cache@v1
if: startsWith(matrix.os, 'macOS')
with:
path: ~/Library/Caches/pip
key:
${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('**/.ci/*.sh') }}
restore-keys: |
${{ matrix.os }}-${{ matrix.python-version }}-
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1 uses: actions/setup-python@v2
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Get pip cache dir
id: pip-cache
run: |
echo "::set-output name=dir::$(pip cache dir)"
- name: pip cache
uses: actions/cache@v2
with:
path: ${{ steps.pip-cache.outputs.dir }}
key:
${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('**/.ci/*.sh') }}
restore-keys: |
${{ matrix.os }}-${{ matrix.python-version }}-
- name: Build system information - name: Build system information
run: python .github/workflows/system-info.py run: python .github/workflows/system-info.py
@ -89,7 +83,7 @@ jobs:
shell: pwsh shell: pwsh
- name: Upload errors - name: Upload errors
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v2
if: failure() if: failure()
with: with:
name: errors name: errors
@ -98,7 +92,7 @@ jobs:
- name: Docs - name: Docs
if: startsWith(matrix.os, 'ubuntu') && matrix.python-version == 3.8 if: startsWith(matrix.os, 'ubuntu') && matrix.python-version == 3.8
run: | run: |
pip install sphinx-rtd-theme pip install sphinx-removed-in sphinx-rtd-theme
make doccheck make doccheck
- name: After success - name: After success

View File

@ -23,7 +23,7 @@ matrix:
arch: arm64 arch: arm64
- python: "3.7" - python: "3.7"
arch: ppc64le arch: ppc64le
- python: "3.5" - python: "3.8"
arch: s390x arch: s390x
- python: "pypy3" - python: "pypy3"
@ -35,16 +35,16 @@ matrix:
name: "3.8 Xenial" name: "3.8 Xenial"
services: xvfb services: xvfb
- python: '3.7' - python: '3.7'
name: "3.7 Xenial" name: "3.7 Xenial PYTHONOPTIMIZE=2"
env: PYTHONOPTIMIZE=2
services: xvfb services: xvfb
- python: '3.6' - python: '3.6'
name: "3.6 Xenial PYTHONOPTIMIZE=1" name: "3.6 Xenial PYTHONOPTIMIZE=1"
env: PYTHONOPTIMIZE=1 env: PYTHONOPTIMIZE=1
services: xvfb services: xvfb
- python: '3.5'
name: "3.5 Xenial PYTHONOPTIMIZE=2" allow_failures:
env: PYTHONOPTIMIZE=2 - python: "3.9-dev"
services: xvfb
install: install:
- | - |

View File

@ -2,9 +2,36 @@
Changelog (Pillow) Changelog (Pillow)
================== ==================
7.2.0 (unreleased) 8.0.0 (unreleased)
------------------ ------------------
- Add MIME type to PsdImagePlugin #4788
[samamorgan]
- Drop support for EOL Python 3.5 #4746
[hugovk, radarhere, nulano]
- Remove ImageCms.CmsProfile attributes deprecated since 3.2.0 #4768
[hugovk, radarhere]
- Allow ImageOps.autocontrast to specify low and high cutoffs separately #4749
[millionhz, radarhere]
7.2.0 (2020-07-01)
------------------
- Do not convert I;16 images when showing PNGs #4744
[radarhere]
- Fixed ICNS file pointer saving #4741
[radarhere]
- Fixed loading non-RGBA mode APNGs with dispose background #4742
[radarhere]
- Deprecated _showxv #4714
[radarhere]
- Deprecate Image.show(command="...") #4646 - Deprecate Image.show(command="...") #4646
[nulano, hugovk, radarhere] [nulano, hugovk, radarhere]
@ -5569,7 +5596,7 @@ Pre-fork
any other pixel value means opaque. This is faster than using an any other pixel value means opaque. This is faster than using an
"L" transparency mask. "L" transparency mask.
+ Properly writes EPS files (and properly prints images to postscript + Properly writes EPS files (and properly prints images to PostScript
printers as well). printers as well).
+ Reads 4-bit BMP files, as well as 4 and 8-bit Windows ICO and CUR + Reads 4-bit BMP files, as well as 4 and 8-bit Windows ICO and CUR
@ -5652,7 +5679,7 @@ Pre-fork
+ Added the "pilfile" utility, which quickly identifies image files + Added the "pilfile" utility, which quickly identifies image files
(without loading them, in most cases). (without loading them, in most cases).
+ Added the "pilprint" utility, which prints image files to Postscript + Added the "pilprint" utility, which prints image files to PostScript
printers. printers.
+ Added a rudimentary version of the "pilview" utility, which is + Added a rudimentary version of the "pilview" utility, which is
@ -5666,5 +5693,5 @@ Pre-fork
Jack). This allows you to read images through the Img extensions file Jack). This allows you to read images through the Img extensions file
format handlers. See the file "Lib/ImgExtImagePlugin.py" for details. format handlers. See the file "Lib/ImgExtImagePlugin.py" for details.
+ Postscript printing is provided through the PSDraw module. See the + PostScript printing is provided through the PSDraw module. See the
handbook for details. handbook for details.

View File

@ -114,3 +114,12 @@ Released as needed privately to individual vendors for critical security-related
## Documentation ## Documentation
* [ ] Make sure the [default version for Read the Docs](https://pillow.readthedocs.io/en/stable/) is up-to-date with the release changes * [ ] Make sure the [default version for Read the Docs](https://pillow.readthedocs.io/en/stable/) is up-to-date with the release changes
## Docker Images
* [ ] Update Pillow in the Docker Images repository
```bash
git clone https://github.com/python-pillow/docker-images
cd docker-images
./update-pillow-tag.sh [[release tag]]
```

View File

@ -165,12 +165,6 @@ def assert_tuple_approx_equal(actuals, targets, threshold, msg):
assert value, msg + ": " + repr(actuals) + " != " + repr(targets) assert value, msg + ": " + repr(actuals) + " != " + repr(targets)
def skip_known_bad_test(msg=None):
# Skip if PILLOW_RUN_KNOWN_BAD is not true in the environment.
if not os.environ.get("PILLOW_RUN_KNOWN_BAD", False):
pytest.skip(msg or "Known bad test")
def skip_unless_feature(feature): def skip_unless_feature(feature):
reason = "%s not available" % feature reason = "%s not available" % feature
return pytest.mark.skipif(not features.check(feature), reason=reason) return pytest.mark.skipif(not features.check(feature), reason=reason)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -104,6 +104,13 @@ def test_apng_dispose_region():
assert im.getpixel((64, 32)) == (0, 255, 0, 255) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
def test_apng_dispose_op_background_p_mode():
with Image.open("Tests/images/apng/dispose_op_background_p_mode.png") as im:
im.seek(1)
im.load()
assert im.size == (128, 64)
def test_apng_blend(): def test_apng_blend():
with Image.open("Tests/images/apng/blend_op_source_solid.png") as im: with Image.open("Tests/images/apng/blend_op_source_solid.png") as im:
im.seek(im.n_frames - 1) im.seek(im.n_frames - 1)
@ -494,6 +501,26 @@ def test_apng_save_disposal(tmp_path):
assert im.getpixel((64, 32)) == (0, 255, 0, 255) assert im.getpixel((64, 32)) == (0, 255, 0, 255)
def test_apng_save_disposal_previous(tmp_path):
test_file = str(tmp_path / "temp.png")
size = (128, 64)
transparent = Image.new("RGBA", size, (0, 0, 0, 0))
red = Image.new("RGBA", size, (255, 0, 0, 255))
green = Image.new("RGBA", size, (0, 255, 0, 255))
# test APNG_DISPOSE_OP_NONE
transparent.save(
test_file,
save_all=True,
append_images=[red, green],
disposal=PngImagePlugin.APNG_DISPOSE_OP_PREVIOUS,
)
with Image.open(test_file) as im:
im.seek(2)
assert im.getpixel((0, 0)) == (0, 255, 0, 255)
assert im.getpixel((64, 32)) == (0, 255, 0, 255)
def test_apng_save_blend(tmp_path): def test_apng_save_blend(tmp_path):
test_file = str(tmp_path / "temp.png") test_file = str(tmp_path / "temp.png")
size = (128, 64) size = (128, 64)

View File

@ -55,6 +55,19 @@ def test_save_append_images(tmp_path):
assert_image_equal(reread, provided_im) assert_image_equal(reread, provided_im)
@pytest.mark.skipif(sys.platform != "darwin", reason="Requires macOS")
def test_save_fp():
fp = io.BytesIO()
with Image.open(TEST_FILE) as im:
im.save(fp, format="ICNS")
with Image.open(fp) as reread:
assert reread.mode == "RGBA"
assert reread.size == (1024, 1024)
assert reread.format == "ICNS"
def test_sizes(): def test_sizes():
# Check that we can load all of the sizes, and that the final pixel # Check that we can load all of the sizes, and that the final pixel
# dimensions are as expected # dimensions are as expected

View File

@ -8,7 +8,6 @@ from .helper import (
assert_image_equal, assert_image_equal,
assert_image_similar, assert_image_similar,
is_big_endian, is_big_endian,
on_ci,
skip_unless_feature, skip_unless_feature,
) )
@ -190,14 +189,14 @@ def test_16bit_monochrome_has_correct_mode():
assert jp2.mode == "I;16" assert jp2.mode == "I;16"
@pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian") @pytest.mark.xfail(is_big_endian(), reason="Fails on big-endian")
def test_16bit_monochrome_jp2_like_tiff(): def test_16bit_monochrome_jp2_like_tiff():
with Image.open("Tests/images/16bit.cropped.tif") as tiff_16bit: with Image.open("Tests/images/16bit.cropped.tif") as tiff_16bit:
with Image.open("Tests/images/16bit.cropped.jp2") as jp2: with Image.open("Tests/images/16bit.cropped.jp2") as jp2:
assert_image_similar(jp2, tiff_16bit, 1e-3) assert_image_similar(jp2, tiff_16bit, 1e-3)
@pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian") @pytest.mark.xfail(is_big_endian(), reason="Fails on big-endian")
def test_16bit_monochrome_j2k_like_tiff(): def test_16bit_monochrome_j2k_like_tiff():
with Image.open("Tests/images/16bit.cropped.tif") as tiff_16bit: with Image.open("Tests/images/16bit.cropped.tif") as tiff_16bit:
with Image.open("Tests/images/16bit.cropped.j2k") as j2k: with Image.open("Tests/images/16bit.cropped.j2k") as j2k:

View File

@ -207,6 +207,7 @@ class TestFileLibTiff(LibTiffTestCase):
del core_items[tag] del core_items[tag]
except KeyError: except KeyError:
pass pass
del core_items[320] # colormap is special, tested below
# Type codes: # Type codes:
# 2: "ascii", # 2: "ascii",
@ -491,6 +492,18 @@ class TestFileLibTiff(LibTiffTestCase):
with Image.open(out) as im2: with Image.open(out) as im2:
assert_image_equal(im, im2) assert_image_equal(im, im2)
def test_palette_save(self, tmp_path):
im = hopper("P")
out = str(tmp_path / "temp.tif")
TiffImagePlugin.WRITE_LIBTIFF = True
im.save(out)
TiffImagePlugin.WRITE_LIBTIFF = False
with Image.open(out) as reloaded:
# colormap/palette tag
assert len(reloaded.tag_v2[320]) == 768
def xtest_bw_compression_w_rgb(self, tmp_path): def xtest_bw_compression_w_rgb(self, tmp_path):
""" This test passes, but when running all tests causes a failure due """ This test passes, but when running all tests causes a failure due
to output on stderr from the error thrown by libtiff. We need to to output on stderr from the error thrown by libtiff. We need to

View File

@ -4,13 +4,7 @@ import subprocess
import pytest import pytest
from PIL import Image from PIL import Image
from .helper import ( from .helper import IMCONVERT, assert_image_equal, hopper, imagemagick_available
IMCONVERT,
assert_image_equal,
hopper,
imagemagick_available,
skip_known_bad_test,
)
_roundtrip = imagemagick_available() _roundtrip = imagemagick_available()
@ -62,13 +56,13 @@ def test_monochrome(tmp_path):
roundtrip(tmp_path, mode) roundtrip(tmp_path, mode)
@pytest.mark.xfail(reason="Palm P image is wrong")
def test_p_mode(tmp_path): def test_p_mode(tmp_path):
# Arrange # Arrange
mode = "P" mode = "P"
# Act / Assert # Act / Assert
helper_save_as_palm(tmp_path, mode) helper_save_as_palm(tmp_path, mode)
skip_known_bad_test("Palm P image is wrong")
roundtrip(tmp_path, mode) roundtrip(tmp_path, mode)

View File

@ -12,7 +12,6 @@ from .helper import (
hopper, hopper,
is_big_endian, is_big_endian,
is_win32, is_win32,
on_ci,
skip_unless_feature, skip_unless_feature,
) )
@ -69,7 +68,7 @@ class TestFilePng:
png.crc(cid, s) png.crc(cid, s)
return chunks return chunks
@pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian") @pytest.mark.xfail(is_big_endian(), reason="Fails on big-endian")
def test_sanity(self, tmp_path): def test_sanity(self, tmp_path):
# internal version number # internal version number

View File

@ -12,6 +12,7 @@ def test_sanity():
assert im.mode == "RGB" assert im.mode == "RGB"
assert im.size == (128, 128) assert im.size == (128, 128)
assert im.format == "PSD" assert im.format == "PSD"
assert im.get_format_mimetype() == "image/vnd.adobe.photoshop"
im2 = hopper() im2 = hopper()
assert_image_similar(im, im2, 4.8) assert_image_similar(im, im2, 4.8)

View File

@ -5,7 +5,6 @@ from .helper import (
assert_image_equal, assert_image_equal,
assert_image_similar, assert_image_similar,
is_big_endian, is_big_endian,
on_ci,
skip_unless_feature, skip_unless_feature,
) )
@ -27,7 +26,7 @@ def test_n_frames():
assert im.is_animated assert im.is_animated
@pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian") @pytest.mark.xfail(is_big_endian(), reason="Fails on big-endian")
def test_write_animation_L(tmp_path): def test_write_animation_L(tmp_path):
""" """
Convert an animated GIF to animated WebP, then compare the frame count, and first Convert an animated GIF to animated WebP, then compare the frame count, and first
@ -53,7 +52,7 @@ def test_write_animation_L(tmp_path):
assert_image_similar(im, orig.convert("RGBA"), 25.0) assert_image_similar(im, orig.convert("RGBA"), 25.0)
@pytest.mark.xfail(is_big_endian() and on_ci(), reason="Fails on big-endian") @pytest.mark.xfail(is_big_endian(), reason="Fails on big-endian")
def test_write_animation_RGB(tmp_path): def test_write_animation_RGB(tmp_path):
""" """
Write an animated WebP from RGB frames, and ensure the frames Write an animated WebP from RGB frames, and ensure the frames

View File

@ -5,7 +5,7 @@ import tempfile
import PIL import PIL
import pytest import pytest
from PIL import Image, ImageDraw, ImagePalette, UnidentifiedImageError from PIL import Image, ImageDraw, ImagePalette, ImageShow, UnidentifiedImageError
from .helper import ( from .helper import (
assert_image_equal, assert_image_equal,
@ -13,6 +13,7 @@ from .helper import (
assert_not_all_same, assert_not_all_same,
hopper, hopper,
is_win32, is_win32,
skip_unless_feature,
) )
@ -585,6 +586,22 @@ class TestImage:
expected = Image.new(mode, (100, 100), color) expected = Image.new(mode, (100, 100), color)
assert_image_equal(im.convert(mode), expected) assert_image_equal(im.convert(mode), expected)
def test_showxv_deprecation(self):
class TestViewer(ImageShow.Viewer):
def show_image(self, image, **options):
return True
viewer = TestViewer()
ImageShow.register(viewer, -1)
im = Image.new("RGB", (50, 50), "white")
with pytest.warns(DeprecationWarning):
Image._showxv(im)
# Restore original state
ImageShow._viewers.pop(0)
def test_no_resource_warning_on_save(self, tmp_path): def test_no_resource_warning_on_save(self, tmp_path):
# https://github.com/python-pillow/Pillow/issues/835 # https://github.com/python-pillow/Pillow/issues/835
# Arrange # Arrange
@ -609,6 +626,97 @@ class TestImage:
assert not fp.closed assert not fp.closed
def test_exif_jpeg(self, tmp_path):
with Image.open("Tests/images/exif-72dpi-int.jpg") as im: # Little endian
exif = im.getexif()
assert 258 not in exif
assert 40960 in exif
assert exif[40963] == 450
assert exif[11] == "gThumb 3.0.1"
out = str(tmp_path / "temp.jpg")
exif[258] = 8
del exif[40960]
exif[40963] = 455
exif[11] = "Pillow test"
im.save(out, exif=exif)
with Image.open(out) as reloaded:
reloaded_exif = reloaded.getexif()
assert reloaded_exif[258] == 8
assert 40960 not in reloaded_exif
assert reloaded_exif[40963] == 455
assert reloaded_exif[11] == "Pillow test"
with Image.open("Tests/images/no-dpi-in-exif.jpg") as im: # Big endian
exif = im.getexif()
assert 258 not in exif
assert 40962 in exif
assert exif[40963] == 200
assert exif[305] == "Adobe Photoshop CC 2017 (Macintosh)"
out = str(tmp_path / "temp.jpg")
exif[258] = 8
del exif[34665]
exif[40963] = 455
exif[305] = "Pillow test"
im.save(out, exif=exif)
with Image.open(out) as reloaded:
reloaded_exif = reloaded.getexif()
assert reloaded_exif[258] == 8
assert 34665 not in reloaded_exif
assert reloaded_exif[40963] == 455
assert reloaded_exif[305] == "Pillow test"
@skip_unless_feature("webp")
@skip_unless_feature("webp_anim")
def test_exif_webp(self, tmp_path):
with Image.open("Tests/images/hopper.webp") as im:
exif = im.getexif()
assert exif == {}
out = str(tmp_path / "temp.webp")
exif[258] = 8
exif[40963] = 455
exif[305] = "Pillow test"
def check_exif():
with Image.open(out) as reloaded:
reloaded_exif = reloaded.getexif()
assert reloaded_exif[258] == 8
assert reloaded_exif[40963] == 455
assert reloaded_exif[305] == "Pillow test"
im.save(out, exif=exif)
check_exif()
im.save(out, exif=exif, save_all=True)
check_exif()
def test_exif_png(self, tmp_path):
with Image.open("Tests/images/exif.png") as im:
exif = im.getexif()
assert exif == {274: 1}
out = str(tmp_path / "temp.png")
exif[258] = 8
del exif[274]
exif[40963] = 455
exif[305] = "Pillow test"
im.save(out, exif=exif)
with Image.open(out) as reloaded:
reloaded_exif = reloaded.getexif()
assert reloaded_exif == {258: 8, 40963: 455, 305: "Pillow test"}
def test_exif_interop(self):
with Image.open("Tests/images/flower.jpg") as im:
exif = im.getexif()
assert exif.get_ifd(0xA005) == {
1: "R98",
2: b"0100",
4097: 2272,
4098: 1704,
}
@pytest.mark.parametrize( @pytest.mark.parametrize(
"test_module", [PIL, Image], "test_module", [PIL, Image],
) )

View File

@ -1,7 +1,7 @@
import pytest import pytest
from PIL import Image, ImageMath, ImageMode from PIL import Image, ImageMath, ImageMode
from .helper import convert_to_comparable from .helper import convert_to_comparable, skip_unless_feature
codecs = dir(Image.core) codecs = dir(Image.core)
@ -254,9 +254,7 @@ def test_mode_F():
compare_reduce_with_box(im, factor) compare_reduce_with_box(im, factor)
@pytest.mark.skipif( @skip_unless_feature("jpg_2000")
"jpeg2k_decoder" not in codecs, reason="JPEG 2000 support not available"
)
def test_jpeg2k(): def test_jpeg2k():
with Image.open("Tests/images/test-card-lossless.jp2") as im: with Image.open("Tests/images/test-card-lossless.jp2") as im:
assert im.reduce(2).size == (320, 240) assert im.reduce(2).size == (320, 240)

View File

@ -218,7 +218,7 @@ class TestImagingCoreResampleAccuracy:
assert_image_equal(im, ref) assert_image_equal(im, ref)
class CoreResampleConsistencyTest: class TestCoreResampleConsistency:
def make_case(self, mode, fill): def make_case(self, mode, fill):
im = Image.new(mode, (512, 9), fill) im = Image.new(mode, (512, 9), fill)
return im.resize((9, 512), Image.LANCZOS), im.load()[0, 0] return im.resize((9, 512), Image.LANCZOS), im.load()[0, 0]
@ -253,7 +253,7 @@ class CoreResampleConsistencyTest:
self.run_case(self.make_case("F", 1.192093e-07)) self.run_case(self.make_case("F", 1.192093e-07))
class CoreResampleAlphaCorrectTest: class TestCoreResampleAlphaCorrect:
def make_levels_case(self, mode): def make_levels_case(self, mode):
i = Image.new(mode, (256, 16)) i = Image.new(mode, (256, 16))
px = i.load() px = i.load()
@ -274,7 +274,7 @@ class CoreResampleAlphaCorrectTest:
len(used_colors), y len(used_colors), y
) )
@pytest.mark.skip("Current implementation isn't precise enough") @pytest.mark.xfail(reason="Current implementation isn't precise enough")
def test_levels_rgba(self): def test_levels_rgba(self):
case = self.make_levels_case("RGBA") case = self.make_levels_case("RGBA")
self.run_levels_case(case.resize((512, 32), Image.BOX)) self.run_levels_case(case.resize((512, 32), Image.BOX))
@ -283,7 +283,7 @@ class CoreResampleAlphaCorrectTest:
self.run_levels_case(case.resize((512, 32), Image.BICUBIC)) self.run_levels_case(case.resize((512, 32), Image.BICUBIC))
self.run_levels_case(case.resize((512, 32), Image.LANCZOS)) self.run_levels_case(case.resize((512, 32), Image.LANCZOS))
@pytest.mark.skip("Current implementation isn't precise enough") @pytest.mark.xfail(reason="Current implementation isn't precise enough")
def test_levels_la(self): def test_levels_la(self):
case = self.make_levels_case("LA") case = self.make_levels_case("LA")
self.run_levels_case(case.resize((512, 32), Image.BOX)) self.run_levels_case(case.resize((512, 32), Image.BOX))
@ -329,7 +329,7 @@ class CoreResampleAlphaCorrectTest:
self.run_dirty_case(case.resize((20, 20), Image.LANCZOS), (255,)) self.run_dirty_case(case.resize((20, 20), Image.LANCZOS), (255,))
class CoreResamplePassesTest: class TestCoreResamplePasses:
@contextmanager @contextmanager
def count(self, diff): def count(self, diff):
count = Image.core.get_stats()["new_count"] count = Image.core.get_stats()["new_count"]
@ -372,7 +372,7 @@ class CoreResamplePassesTest:
assert_image_similar(with_box, cropped, 0.1) assert_image_similar(with_box, cropped, 0.1)
class CoreResampleCoefficientsTest: class TestCoreResampleCoefficients:
def test_reduce(self): def test_reduce(self):
test_color = 254 test_color = 254
@ -401,7 +401,7 @@ class CoreResampleCoefficientsTest:
assert histogram[0x100 * 3 + 0xFF] == 0x10000 assert histogram[0x100 * 3 + 0xFF] == 0x10000
class CoreResampleBoxTest: class TestCoreResampleBox:
def test_wrong_arguments(self): def test_wrong_arguments(self):
im = hopper() im = hopper()
for resample in ( for resample in (

View File

@ -435,39 +435,6 @@ def test_extended_information():
assert p.xcolor_space == "RGB " assert p.xcolor_space == "RGB "
def test_deprecations():
skip_missing()
o = ImageCms.getOpenProfile(SRGB)
p = o.profile
def helper_deprecated(attr, expected):
result = pytest.warns(DeprecationWarning, getattr, p, attr)
assert result == expected
# p.color_space
helper_deprecated("color_space", "RGB")
# p.pcs
helper_deprecated("pcs", "XYZ")
# p.product_copyright
helper_deprecated(
"product_copyright", "Copyright International Color Consortium, 2009"
)
# p.product_desc
helper_deprecated("product_desc", "sRGB IEC61966-2-1 black scaled")
# p.product_description
helper_deprecated("product_description", "sRGB IEC61966-2-1 black scaled")
# p.product_manufacturer
helper_deprecated("product_manufacturer", "")
# p.product_model
helper_deprecated("product_model", "IEC 61966-2-1 Default RGB Colour Space - sRGB")
def test_profile_typesafety(): def test_profile_typesafety():
""" Profile init type safety """ Profile init type safety

View File

@ -243,94 +243,3 @@ class TestPyDecoder:
im = MockImageFile(buf) im = MockImageFile(buf)
assert im.format is None assert im.format is None
assert im.get_format_mimetype() is None assert im.get_format_mimetype() is None
def test_exif_jpeg(self, tmp_path):
with Image.open("Tests/images/exif-72dpi-int.jpg") as im: # Little endian
exif = im.getexif()
assert 258 not in exif
assert 40960 in exif
assert exif[40963] == 450
assert exif[11] == "gThumb 3.0.1"
out = str(tmp_path / "temp.jpg")
exif[258] = 8
del exif[40960]
exif[40963] = 455
exif[11] = "Pillow test"
im.save(out, exif=exif)
with Image.open(out) as reloaded:
reloaded_exif = reloaded.getexif()
assert reloaded_exif[258] == 8
assert 40960 not in reloaded_exif
assert reloaded_exif[40963] == 455
assert reloaded_exif[11] == "Pillow test"
with Image.open("Tests/images/no-dpi-in-exif.jpg") as im: # Big endian
exif = im.getexif()
assert 258 not in exif
assert 40962 in exif
assert exif[40963] == 200
assert exif[305] == "Adobe Photoshop CC 2017 (Macintosh)"
out = str(tmp_path / "temp.jpg")
exif[258] = 8
del exif[34665]
exif[40963] = 455
exif[305] = "Pillow test"
im.save(out, exif=exif)
with Image.open(out) as reloaded:
reloaded_exif = reloaded.getexif()
assert reloaded_exif[258] == 8
assert 34665 not in reloaded_exif
assert reloaded_exif[40963] == 455
assert reloaded_exif[305] == "Pillow test"
@skip_unless_feature("webp")
@skip_unless_feature("webp_anim")
def test_exif_webp(self, tmp_path):
with Image.open("Tests/images/hopper.webp") as im:
exif = im.getexif()
assert exif == {}
out = str(tmp_path / "temp.webp")
exif[258] = 8
exif[40963] = 455
exif[305] = "Pillow test"
def check_exif():
with Image.open(out) as reloaded:
reloaded_exif = reloaded.getexif()
assert reloaded_exif[258] == 8
assert reloaded_exif[40963] == 455
assert reloaded_exif[305] == "Pillow test"
im.save(out, exif=exif)
check_exif()
im.save(out, exif=exif, save_all=True)
check_exif()
def test_exif_png(self, tmp_path):
with Image.open("Tests/images/exif.png") as im:
exif = im.getexif()
assert exif == {274: 1}
out = str(tmp_path / "temp.png")
exif[258] = 8
del exif[274]
exif[40963] = 455
exif[305] = "Pillow test"
im.save(out, exif=exif)
with Image.open(out) as reloaded:
reloaded_exif = reloaded.getexif()
assert reloaded_exif == {258: 8, 40963: 455, 305: "Pillow test"}
def test_exif_interop(self):
with Image.open("Tests/images/flower.jpg") as im:
exif = im.getexif()
assert exif.get_ifd(0xA005) == {
1: "R98",
2: b"0100",
4097: 2272,
4098: 1704,
}

View File

@ -1,5 +1,4 @@
import copy import copy
import distutils.version
import os import os
import re import re
import shutil import shutil
@ -7,6 +6,7 @@ import sys
from io import BytesIO from io import BytesIO
import pytest import pytest
from packaging.version import parse as parse_version
from PIL import Image, ImageDraw, ImageFont, features from PIL import Image, ImageDraw, ImageFont, features
from .helper import ( from .helper import (
@ -59,7 +59,7 @@ class TestImageFont:
@classmethod @classmethod
def setup_class(self): def setup_class(self):
freetype = distutils.version.StrictVersion(features.version_module("freetype2")) freetype = parse_version(features.version_module("freetype2"))
self.metrics = self.METRICS["Default"] self.metrics = self.METRICS["Default"]
for conditions, metrics in self.METRICS.items(): for conditions, metrics in self.METRICS.items():
@ -67,7 +67,7 @@ class TestImageFont:
continue continue
for condition in conditions: for condition in conditions:
version = re.sub("[<=>]", "", condition) version = parse_version(re.sub("[<=>]", "", condition))
if (condition.startswith(">=") and freetype >= version) or ( if (condition.startswith(">=") and freetype >= version) or (
condition.startswith("<") and freetype < version condition.startswith("<") and freetype < version
): ):
@ -501,7 +501,7 @@ class TestImageFont:
with pytest.raises(UnicodeEncodeError): with pytest.raises(UnicodeEncodeError):
font.getsize("") font.getsize("")
@pytest.mark.skipif(is_pypy(), reason="failing on PyPy") @pytest.mark.xfail(is_pypy(), reason="failing on PyPy with Raqm")
def test_unicode_extended(self): def test_unicode_extended(self):
# issue #3777 # issue #3777
text = "A\u278A\U0001F12B" text = "A\u278A\U0001F12B"
@ -667,8 +667,8 @@ class TestImageFont:
def test_variation_get(self): def test_variation_get(self):
font = self.get_font() font = self.get_font()
freetype = distutils.version.StrictVersion(features.version_module("freetype2")) freetype = parse_version(features.version_module("freetype2"))
if freetype < "2.9.1": if freetype < parse_version("2.9.1"):
with pytest.raises(NotImplementedError): with pytest.raises(NotImplementedError):
font.get_variation_names() font.get_variation_names()
with pytest.raises(NotImplementedError): with pytest.raises(NotImplementedError):
@ -739,8 +739,8 @@ class TestImageFont:
def test_variation_set_by_name(self): def test_variation_set_by_name(self):
font = self.get_font() font = self.get_font()
freetype = distutils.version.StrictVersion(features.version_module("freetype2")) freetype = parse_version(features.version_module("freetype2"))
if freetype < "2.9.1": if freetype < parse_version("2.9.1"):
with pytest.raises(NotImplementedError): with pytest.raises(NotImplementedError):
font.set_variation_by_name("Bold") font.set_variation_by_name("Bold")
return return
@ -763,8 +763,8 @@ class TestImageFont:
def test_variation_set_by_axes(self): def test_variation_set_by_axes(self):
font = self.get_font() font = self.get_font()
freetype = distutils.version.StrictVersion(features.version_module("freetype2")) freetype = parse_version(features.version_module("freetype2"))
if freetype < "2.9.1": if freetype < parse_version("2.9.1"):
with pytest.raises(NotImplementedError): with pytest.raises(NotImplementedError):
font.set_variation_by_axes([100]) font.set_variation_by_axes([100])
return return
@ -871,7 +871,7 @@ class TestImageFont_RaqmLayout(TestImageFont):
def test_render_mono_size(): def test_render_mono_size():
# issue 4177 # issue 4177
if distutils.version.StrictVersion(ImageFont.core.freetype2_version) < "2.4": if parse_version(ImageFont.core.freetype2_version) < parse_version("2.4"):
pytest.skip("Different metrics") pytest.skip("Different metrics")
im = Image.new("P", (100, 30), "white") im = Image.new("P", (100, 30), "white")

View File

@ -5,7 +5,7 @@ import sys
import pytest import pytest
from PIL import Image, ImageGrab from PIL import Image, ImageGrab
from .helper import assert_image, assert_image_equal_tofile from .helper import assert_image, assert_image_equal_tofile, skip_unless_feature
class TestImageGrab: class TestImageGrab:
@ -23,7 +23,7 @@ class TestImageGrab:
im = ImageGrab.grab(bbox=(10, 20, 50, 80)) im = ImageGrab.grab(bbox=(10, 20, 50, 80))
assert_image(im, im.mode, (40, 60)) assert_image(im, im.mode, (40, 60))
@pytest.mark.skipif(not Image.core.HAVE_XCB, reason="requires XCB") @skip_unless_feature("xcb")
def test_grab_x11(self): def test_grab_x11(self):
try: try:
if sys.platform not in ("win32", "darwin"): if sys.platform not in ("win32", "darwin"):
@ -46,7 +46,7 @@ class TestImageGrab:
ImageGrab.grab(xdisplay="") ImageGrab.grab(xdisplay="")
assert str(e.value).startswith("Pillow was built without XCB support") assert str(e.value).startswith("Pillow was built without XCB support")
@pytest.mark.skipif(not Image.core.HAVE_XCB, reason="requires XCB") @skip_unless_feature("xcb")
def test_grab_invalid_xdisplay(self): def test_grab_invalid_xdisplay(self):
with pytest.raises(OSError) as e: with pytest.raises(OSError) as e:
ImageGrab.grab(xdisplay="error.test:0.0") ImageGrab.grab(xdisplay="error.test:0.0")

View File

@ -300,3 +300,14 @@ def test_exif_transpose():
"Tests/images/hopper_orientation_" + str(i) + ext "Tests/images/hopper_orientation_" + str(i) + ext
) as orientation_im: ) as orientation_im:
check(orientation_im) check(orientation_im)
def test_autocontrast_cutoff():
# Test the cutoff argument of autocontrast
with Image.open("Tests/images/bw_gradient.png") as img:
def autocontrast(cutoff):
return ImageOps.autocontrast(img, cutoff).histogram()
assert autocontrast(10) == autocontrast((10, 10))
assert autocontrast(10) != autocontrast((1, 10))

View File

@ -4,106 +4,97 @@ PIL Package (autodoc of remaining modules)
Reference for modules whose documentation has not yet been ported or written Reference for modules whose documentation has not yet been ported or written
can be found here. can be found here.
:mod:`BdfFontFile` Module :mod:`PIL` Module
------------------------- -----------------
.. py:module:: PIL
.. autoexception:: UnidentifiedImageError
:show-inheritance:
:mod:`~PIL.BdfFontFile` Module
------------------------------
.. automodule:: PIL.BdfFontFile .. automodule:: PIL.BdfFontFile
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`ContainerIO` Module :mod:`~PIL.ContainerIO` Module
------------------------- ------------------------------
.. automodule:: PIL.ContainerIO .. automodule:: PIL.ContainerIO
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`FontFile` Module :mod:`~PIL.FontFile` Module
---------------------- ---------------------------
.. automodule:: PIL.FontFile .. automodule:: PIL.FontFile
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`GdImageFile` Module :mod:`~PIL.GdImageFile` Module
------------------------- ------------------------------
.. automodule:: PIL.GdImageFile .. automodule:: PIL.GdImageFile
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`GimpGradientFile` Module :mod:`~PIL.GimpGradientFile` Module
------------------------------ -----------------------------------
.. automodule:: PIL.GimpGradientFile .. automodule:: PIL.GimpGradientFile
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`GimpPaletteFile` Module :mod:`~PIL.GimpPaletteFile` Module
----------------------------- ----------------------------------
.. automodule:: PIL.GimpPaletteFile .. automodule:: PIL.GimpPaletteFile
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
.. intentionally skipped documenting this because it's not documented anywhere :mod:`~PIL.ImageDraw2` Module
-----------------------------
:mod:`ImageDraw2` Module
------------------------
.. automodule:: PIL.ImageDraw2 .. automodule:: PIL.ImageDraw2
:members: :members:
:member-order: bysource
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`ImageShow` Module :mod:`~PIL.ImageTransform` Module
----------------------- ---------------------------------
.. automodule:: PIL.ImageShow
:members:
:undoc-members:
:show-inheritance:
:mod:`ImageTransform` Module
----------------------------
.. automodule:: PIL.ImageTransform .. automodule:: PIL.ImageTransform
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`JpegPresets` Module :mod:`~PIL.PaletteFile` Module
------------------------- ------------------------------
.. automodule:: PIL.JpegPresets
:members:
:undoc-members:
:show-inheritance:
:mod:`PaletteFile` Module
-------------------------
.. automodule:: PIL.PaletteFile .. automodule:: PIL.PaletteFile
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`PcfFontFile` Module :mod:`~PIL.PcfFontFile` Module
------------------------- ------------------------------
.. automodule:: PIL.PcfFontFile .. automodule:: PIL.PcfFontFile
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:class:`PngImagePlugin.iTXt` Class :class:`.PngImagePlugin.iTXt` Class
---------------------------------- -----------------------------------
.. autoclass:: PIL.PngImagePlugin.iTXt .. autoclass:: PIL.PngImagePlugin.iTXt
:members: :members:
@ -116,8 +107,8 @@ can be found here.
:param lang: language code :param lang: language code
:param tkey: UTF-8 version of the key name :param tkey: UTF-8 version of the key name
:class:`PngImagePlugin.PngInfo` Class :class:`.PngImagePlugin.PngInfo` Class
------------------------------------- --------------------------------------
.. autoclass:: PIL.PngImagePlugin.PngInfo .. autoclass:: PIL.PngImagePlugin.PngInfo
:members: :members:
@ -125,27 +116,18 @@ can be found here.
:show-inheritance: :show-inheritance:
:mod:`TarIO` Module :mod:`~PIL.TarIO` Module
------------------- ------------------------
.. automodule:: PIL.TarIO .. automodule:: PIL.TarIO
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`WalImageFile` Module :mod:`~PIL.WalImageFile` Module
-------------------------- -------------------------------
.. automodule:: PIL.WalImageFile .. automodule:: PIL.WalImageFile
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`_binary` Module
---------------------
.. automodule:: PIL._binary
:members:
:undoc-members:
:show-inheritance:

View File

@ -22,12 +22,19 @@ import sphinx_rtd_theme
# -- General configuration ------------------------------------------------ # -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here. # If your documentation needs a minimal Sphinx version, state it here.
# needs_sphinx = '1.0' needs_sphinx = "2.4"
# Add any Sphinx extension module names here, as strings. They can be # Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones. # ones.
extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx.ext.intersphinx"] extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.viewcode",
"sphinx_removed_in",
]
intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}
# The suffix(es) of source filenames. # The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string: # You can specify multiple suffix as a list of string:
@ -98,6 +105,22 @@ pygments_style = "sphinx"
# If true, `todo` and `todoList` produce output, else they produce nothing. # If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False todo_include_todos = False
# If true, Sphinx will warn about all references where the target cannot be found.
# Default is False. You can activate this mode temporarily using the -n command-line
# switch.
nitpicky = True
# A list of (type, target) tuples (by default empty) that should be ignored when
# generating warnings in “nitpicky mode”. Note that type should include the domain name
# if present. Example entries would be ('py:func', 'int') or
# ('envvar', 'LD_LIBRARY_PATH').
nitpick_ignore = [
("py:attr", "PIL.Image.Image.tag"),
("py:attr", "PIL.Image.Image.tag_v2"),
("py:attr", "PIL.Image.Image.tile"),
("py:attr", "PIL.TiffImagePlugin.ImageFileDirectory_v2.tagtype"),
]
# -- Options for HTML output ---------------------------------------------- # -- Options for HTML output ----------------------------------------------

View File

@ -20,6 +20,15 @@ Image.show command parameter
The ``command`` parameter was deprecated and will be removed in a future release. The ``command`` parameter was deprecated and will be removed in a future release.
Use a subclass of ``ImageShow.Viewer`` instead. Use a subclass of ``ImageShow.Viewer`` instead.
Image._showxv
~~~~~~~~~~~~~
.. deprecated:: 7.2.0
``Image._showxv`` has been deprecated. Use :py:meth:`~PIL.Image.Image.show`
instead. If custom behaviour is required, use :py:meth:`~PIL.ImageShow.register` to add
a custom :py:class:`~PIL.ImageShow.Viewer` class.
ImageFile.raise_ioerror ImageFile.raise_ioerror
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
@ -40,16 +49,23 @@ PILLOW_VERSION constant
It was initially removed in Pillow 7.0.0, but brought back in 7.1.0 to give projects It was initially removed in Pillow 7.0.0, but brought back in 7.1.0 to give projects
more time to upgrade. more time to upgrade.
Removed features
----------------
Deprecated features are only removed in major releases after an appropriate
period of deprecation has passed.
ImageCms.CmsProfile attributes ImageCms.CmsProfile attributes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 3.2.0 .. deprecated:: 3.2.0
.. versionremoved:: 8.0.0
Some attributes in ``ImageCms.CmsProfile`` are deprecated. From 6.0.0, they issue a Some attributes in ``ImageCms.CmsProfile`` have been removed. From 6.0.0, they issued a
``DeprecationWarning``: ``DeprecationWarning``:
======================== =============================== ======================== ===============================
Deprecated Use instead Removed Use instead
======================== =============================== ======================== ===============================
``color_space`` Padded ``xcolor_space`` ``color_space`` Padded ``xcolor_space``
``pcs`` Padded ``connection_space`` ``pcs`` Padded ``connection_space``
@ -60,16 +76,11 @@ Deprecated Use instead
``product_model`` Unicode ``model`` ``product_model`` Unicode ``model``
======================== =============================== ======================== ===============================
Removed features
----------------
Deprecated features are only removed in major releases after an appropriate
period of deprecation has passed.
Python 2.7 Python 2.7
~~~~~~~~~~ ~~~~~~~~~~
*Removed in version 7.0.0.* .. deprecated:: 6.0.0
.. versionremoved:: 7.0.0
Python 2.7 reached end-of-life on 2020-01-01. Pillow 6.x was the last series to Python 2.7 reached end-of-life on 2020-01-01. Pillow 6.x was the last series to
support Python 2. support Python 2.
@ -77,7 +88,8 @@ support Python 2.
Image.__del__ Image.__del__
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
*Removed in version 7.0.0.* .. deprecated:: 6.1.0
.. versionremoved:: 7.0.0
Implicitly closing the image's underlying file in ``Image.__del__`` has been removed. Implicitly closing the image's underlying file in ``Image.__del__`` has been removed.
Use a context manager or call ``Image.close()`` instead to close the file in a Use a context manager or call ``Image.close()`` instead to close the file in a
@ -100,7 +112,8 @@ Use instead:
PIL.*ImagePlugin.__version__ attributes PIL.*ImagePlugin.__version__ attributes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Removed in version 7.0.0.* .. deprecated:: 6.0.0
.. versionremoved:: 7.0.0
The version constants of individual plugins have been removed. Use ``PIL.__version__`` The version constants of individual plugins have been removed. Use ``PIL.__version__``
instead. instead.
@ -125,7 +138,8 @@ Removed Removed Removed
PyQt4 and PySide PyQt4 and PySide
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
*Removed in version 7.0.0.* .. deprecated:: 6.0.0
.. versionremoved:: 7.0.0
Qt 4 reached end-of-life on 2015-12-19. Its Python bindings are also EOL: PyQt4 since Qt 4 reached end-of-life on 2015-12-19. Its Python bindings are also EOL: PyQt4 since
2018-08-31 and PySide since 2015-10-14. 2018-08-31 and PySide since 2015-10-14.
@ -136,7 +150,8 @@ or PySide2.
Setting the size of TIFF images Setting the size of TIFF images
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Removed in version 7.0.0.* .. deprecated:: 5.3.0
.. versionremoved:: 7.0.0
Setting the size of a TIFF image directly (eg. ``im.size = (256, 256)``) throws Setting the size of a TIFF image directly (eg. ``im.size = (256, 256)``) throws
an error. Use ``Image.resize`` instead. an error. Use ``Image.resize`` instead.
@ -144,7 +159,8 @@ an error. Use ``Image.resize`` instead.
VERSION constant VERSION constant
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
*Removed in version 6.0.0.* .. deprecated:: 5.2.0
.. versionremoved:: 6.0.0
``VERSION`` (the old PIL version, always 1.1.7) has been removed. Use ``VERSION`` (the old PIL version, always 1.1.7) has been removed. Use
``__version__`` instead. ``__version__`` instead.
@ -152,7 +168,8 @@ VERSION constant
Undocumented ImageOps functions Undocumented ImageOps functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Removed in version 6.0.0.* .. deprecated:: 4.3.0
.. versionremoved:: 6.0.0
Several undocumented functions in ``ImageOps`` have been removed. Use the equivalents Several undocumented functions in ``ImageOps`` have been removed. Use the equivalents
in ``ImageFilter`` instead: in ``ImageFilter`` instead:
@ -170,7 +187,8 @@ Removed Use instead
PIL.OleFileIO PIL.OleFileIO
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
*Removed in version 6.0.0.* .. deprecated:: 4.0.0
.. versionremoved:: 6.0.0
PIL.OleFileIO was removed as a vendored file and in Pillow 4.0.0 (2017-01) in favour of PIL.OleFileIO was removed as a vendored file and in Pillow 4.0.0 (2017-01) in favour of
the upstream olefile Python package, and replaced with an ``ImportError`` in 5.0.0 the upstream olefile Python package, and replaced with an ``ImportError`` in 5.0.0

View File

@ -249,8 +249,8 @@ class DXT1Decoder(ImageFile.PyDecoder):
def decode(self, buffer): def decode(self, buffer):
try: try:
self.set_as_raw(_dxt1(self.fd, self.state.xsize, self.state.ysize)) self.set_as_raw(_dxt1(self.fd, self.state.xsize, self.state.ysize))
except struct.error: except struct.error as e:
raise OSError("Truncated DDS file") raise OSError("Truncated DDS file") from e
return 0, 0 return 0, 0
@ -260,8 +260,8 @@ class DXT5Decoder(ImageFile.PyDecoder):
def decode(self, buffer): def decode(self, buffer):
try: try:
self.set_as_raw(_dxt5(self.fd, self.state.xsize, self.state.ysize)) self.set_as_raw(_dxt5(self.fd, self.state.xsize, self.state.ysize))
except struct.error: except struct.error as e:
raise OSError("Truncated DDS file") raise OSError("Truncated DDS file") from e
return 0, 0 return 0, 0

View File

@ -121,39 +121,47 @@ Filters
For geometry operations that may map multiple input pixels to a single output For geometry operations that may map multiple input pixels to a single output
pixel, the Python Imaging Library provides different resampling *filters*. pixel, the Python Imaging Library provides different resampling *filters*.
``NEAREST`` .. py:currentmodule:: PIL.Image
.. data:: NEAREST
Pick one nearest pixel from the input image. Ignore all other input pixels. Pick one nearest pixel from the input image. Ignore all other input pixels.
``BOX`` .. data:: BOX
Each pixel of source image contributes to one pixel of the Each pixel of source image contributes to one pixel of the
destination image with identical weights. destination image with identical weights.
For upscaling is equivalent of ``NEAREST``. For upscaling is equivalent of :data:`NEAREST`.
This filter can only be used with the :py:meth:`~PIL.Image.Image.resize` This filter can only be used with the :py:meth:`~PIL.Image.Image.resize`
and :py:meth:`~PIL.Image.Image.thumbnail` methods. and :py:meth:`~PIL.Image.Image.thumbnail` methods.
.. versionadded:: 3.4.0 .. versionadded:: 3.4.0
``BILINEAR`` .. data:: BILINEAR
For resize calculate the output pixel value using linear interpolation For resize calculate the output pixel value using linear interpolation
on all pixels that may contribute to the output value. on all pixels that may contribute to the output value.
For other transformations linear interpolation over a 2x2 environment For other transformations linear interpolation over a 2x2 environment
in the input image is used. in the input image is used.
``HAMMING`` .. data:: HAMMING
Produces a sharper image than ``BILINEAR``, doesn't have dislocations
on local level like with ``BOX``. Produces a sharper image than :data:`BILINEAR`, doesn't have dislocations
on local level like with :data:`BOX`.
This filter can only be used with the :py:meth:`~PIL.Image.Image.resize` This filter can only be used with the :py:meth:`~PIL.Image.Image.resize`
and :py:meth:`~PIL.Image.Image.thumbnail` methods. and :py:meth:`~PIL.Image.Image.thumbnail` methods.
.. versionadded:: 3.4.0 .. versionadded:: 3.4.0
``BICUBIC`` .. data:: BICUBIC
For resize calculate the output pixel value using cubic interpolation For resize calculate the output pixel value using cubic interpolation
on all pixels that may contribute to the output value. on all pixels that may contribute to the output value.
For other transformations cubic interpolation over a 4x4 environment For other transformations cubic interpolation over a 4x4 environment
in the input image is used. in the input image is used.
``LANCZOS`` .. data:: LANCZOS
Calculate the output pixel value using a high-quality Lanczos filter (a Calculate the output pixel value using a high-quality Lanczos filter (a
truncated sinc) on all pixels that may contribute to the output value. truncated sinc) on all pixels that may contribute to the output value.
This filter can only be used with the :py:meth:`~PIL.Image.Image.resize` This filter can only be used with the :py:meth:`~PIL.Image.Image.resize`
@ -165,19 +173,19 @@ pixel, the Python Imaging Library provides different resampling *filters*.
Filters comparison table Filters comparison table
~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~
+------------+-------------+-----------+-------------+ +----------------+-------------+-----------+-------------+
| Filter | Downscaling | Upscaling | Performance | | Filter | Downscaling | Upscaling | Performance |
| | quality | quality | | | | quality | quality | |
+============+=============+===========+=============+ +================+=============+===========+=============+
|``NEAREST`` | | | ⭐⭐⭐⭐⭐ | |:data:`NEAREST` | | | ⭐⭐⭐⭐⭐ |
+------------+-------------+-----------+-------------+ +----------------+-------------+-----------+-------------+
|``BOX`` | ⭐ | | ⭐⭐⭐⭐ | |:data:`BOX` | ⭐ | | ⭐⭐⭐⭐ |
+------------+-------------+-----------+-------------+ +----------------+-------------+-----------+-------------+
|``BILINEAR``| ⭐ | ⭐ | ⭐⭐⭐ | |:data:`BILINEAR`| ⭐ | ⭐ | ⭐⭐⭐ |
+------------+-------------+-----------+-------------+ +----------------+-------------+-----------+-------------+
|``HAMMING`` | ⭐⭐ | | ⭐⭐⭐ | |:data:`HAMMING` | ⭐⭐ | | ⭐⭐⭐ |
+------------+-------------+-----------+-------------+ +----------------+-------------+-----------+-------------+
|``BICUBIC`` | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | |:data:`BICUBIC` | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
+------------+-------------+-----------+-------------+ +----------------+-------------+-----------+-------------+
|``LANCZOS`` | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ | |:data:`LANCZOS` | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ |
+------------+-------------+-----------+-------------+ +----------------+-------------+-----------+-------------+

View File

@ -8,7 +8,7 @@ Over 30 different file formats can be identified and read by the library.
Write support is less extensive, but most common interchange and presentation Write support is less extensive, but most common interchange and presentation
formats are supported. formats are supported.
The :py:meth:`~PIL.Image.Image.open` function identifies files from their The :py:meth:`~PIL.Image.open` function identifies files from their
contents, not their names, but the :py:meth:`~PIL.Image.Image.save` method contents, not their names, but the :py:meth:`~PIL.Image.Image.save` method
looks at the name to determine which format to use, unless the format is given looks at the name to determine which format to use, unless the format is given
explicitly. explicitly.
@ -25,7 +25,7 @@ Pillow reads and writes Windows and OS/2 BMP files containing ``1``, ``L``, ``P`
or ``RGB`` data. 16-colour images are read as ``P`` images. Run-length encoding or ``RGB`` data. 16-colour images are read as ``P`` images. Run-length encoding
is not supported. is not supported.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**compression** **compression**
@ -74,7 +74,7 @@ are used or GIF89a is already in use.
Note that GIF files are always read as grayscale (``L``) Note that GIF files are always read as grayscale (``L``)
or palette mode (``P``) images. or palette mode (``P``) images.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**background** **background**
@ -203,7 +203,7 @@ ICNS
Pillow reads and (macOS only) writes macOS ``.icns`` files. By default, the Pillow reads and (macOS only) writes macOS ``.icns`` files. By default, the
largest available icon is read, though you can override this by setting the largest available icon is read, though you can override this by setting the
:py:attr:`~PIL.Image.Image.size` property before calling :py:attr:`~PIL.Image.Image.size` property before calling
:py:meth:`~PIL.Image.Image.load`. The :py:meth:`~PIL.Image.Image.open` method :py:meth:`~PIL.Image.Image.load`. The :py:meth:`~PIL.Image.open` method
sets the following :py:attr:`~PIL.Image.Image.info` property: sets the following :py:attr:`~PIL.Image.Image.info` property:
**sizes** **sizes**
@ -257,7 +257,7 @@ Using the :py:meth:`~PIL.Image.Image.draft` method, you can speed things up by
converting ``RGB`` images to ``L``, and resize images to 1/2, 1/4 or 1/8 of converting ``RGB`` images to ``L``, and resize images to 1/2, 1/4 or 1/8 of
their original size while loading them. their original size while loading them.
The :py:meth:`~PIL.Image.Image.open` method may set the following The :py:meth:`~PIL.Image.open` method may set the following
:py:attr:`~PIL.Image.Image.info` properties if available: :py:attr:`~PIL.Image.Image.info` properties if available:
**jfif** **jfif**
@ -473,7 +473,7 @@ image formats, EXIF data is not guaranteed to be present in
:py:attr:`~PIL.Image.Image.info` until :py:meth:`~PIL.Image.Image.load` has been :py:attr:`~PIL.Image.Image.info` until :py:meth:`~PIL.Image.Image.load` has been
called. called.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:func:`~PIL.Image.open` function sets the following
:py:attr:`~PIL.Image.Image.info` properties, when appropriate: :py:attr:`~PIL.Image.Image.info` properties, when appropriate:
**chromaticity** **chromaticity**
@ -501,12 +501,14 @@ The :py:meth:`~PIL.Image.Image.open` method sets the following
This key is omitted if the image is not a transparent palette image. This key is omitted if the image is not a transparent palette image.
.. _png-text:
``open`` also sets ``Image.text`` to a dictionary of the values of the ``open`` also sets ``Image.text`` to a dictionary of the values of the
``tEXt``, ``zTXt``, and ``iTXt`` chunks of the PNG image. Individual ``tEXt``, ``zTXt``, and ``iTXt`` chunks of the PNG image. Individual
compressed chunks are limited to a decompressed size of compressed chunks are limited to a decompressed size of
``PngImagePlugin.MAX_TEXT_CHUNK``, by default 1MB, to prevent :data:`.PngImagePlugin.MAX_TEXT_CHUNK`, by default 1MB, to prevent
decompression bombs. Additionally, the total size of all of the text decompression bombs. Additionally, the total size of all of the text
chunks is limited to ``PngImagePlugin.MAX_TEXT_MEMORY``, defaulting to chunks is limited to :data:`.PngImagePlugin.MAX_TEXT_MEMORY`, defaulting to
64MB. 64MB.
The :py:meth:`~PIL.Image.Image.save` method supports the following options: The :py:meth:`~PIL.Image.Image.save` method supports the following options:
@ -611,6 +613,8 @@ where applicable:
Any APNG file containing sequence errors is treated as an invalid image. The APNG Any APNG file containing sequence errors is treated as an invalid image. The APNG
loader will not attempt to repair and reorder files containing sequence errors. loader will not attempt to repair and reorder files containing sequence errors.
.. _apng-saving:
Saving Saving
~~~~~~ ~~~~~~
@ -697,7 +701,7 @@ Pillow also reads SPIDER stack files containing sequences of SPIDER images. The
:py:meth:`~PIL.Image.Image.seek` and :py:meth:`~PIL.Image.Image.tell` methods are supported, and :py:meth:`~PIL.Image.Image.seek` and :py:meth:`~PIL.Image.Image.tell` methods are supported, and
random access is allowed. random access is allowed.
The :py:meth:`~PIL.Image.Image.open` method sets the following attributes: The :py:meth:`~PIL.Image.open` method sets the following attributes:
**format** **format**
Set to ``SPIDER`` Set to ``SPIDER``
@ -708,8 +712,8 @@ The :py:meth:`~PIL.Image.Image.open` method sets the following attributes:
**n_frames** **n_frames**
Set to the number of images in the stack. Set to the number of images in the stack.
A convenience method, :py:meth:`~PIL.Image.Image.convert2byte`, is provided for A convenience method, :py:meth:`~PIL.SpiderImagePlugin.SpiderImageFile.convert2byte`,
converting floating point data to byte data (mode ``L``):: is provided for converting floating point data to byte data (mode ``L``)::
im = Image.open('image001.spi').convert2byte() im = Image.open('image001.spi').convert2byte()
@ -750,7 +754,7 @@ uncompressed files.
support for reading Packbits, LZW and JPEG compressed TIFFs support for reading Packbits, LZW and JPEG compressed TIFFs
without using libtiff. without using libtiff.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**compression** **compression**
@ -774,7 +778,7 @@ The :py:meth:`~PIL.Image.Image.open` method sets the following
The :py:attr:`~PIL.Image.Image.tag_v2` attribute contains a dictionary The :py:attr:`~PIL.Image.Image.tag_v2` attribute contains a dictionary
of TIFF metadata. The keys are numerical indexes from of TIFF metadata. The keys are numerical indexes from
:py:attr:`~PIL.TiffTags.TAGS_V2`. Values are strings or numbers for single :py:data:`.TiffTags.TAGS_V2`. Values are strings or numbers for single
items, multiple values are returned in a tuple of values. Rational items, multiple values are returned in a tuple of values. Rational
numbers are returned as a :py:class:`~PIL.TiffImagePlugin.IFDRational` numbers are returned as a :py:class:`~PIL.TiffImagePlugin.IFDRational`
object. object.
@ -827,7 +831,7 @@ The :py:meth:`~PIL.Image.Image.save` method can take the following keyword argum
object and setting the type in object and setting the type in
:py:attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v2.tagtype` with :py:attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v2.tagtype` with
the appropriate numerical value from the appropriate numerical value from
``TiffTags.TYPES``. :py:data:`.TiffTags.TYPES`.
.. versionadded:: 2.3.0 .. versionadded:: 2.3.0
@ -844,7 +848,7 @@ The :py:meth:`~PIL.Image.Image.save` method can take the following keyword argum
Previous versions only supported some tags when writing using Previous versions only supported some tags when writing using
libtiff. The supported list is found in libtiff. The supported list is found in
:py:attr:`~PIL:TiffTags.LIBTIFF_CORE`. :py:data:`.TiffTags.LIBTIFF_CORE`.
.. versionadded:: 6.1.0 .. versionadded:: 6.1.0
@ -857,7 +861,7 @@ The :py:meth:`~PIL.Image.Image.save` method can take the following keyword argum
**compression** **compression**
A string containing the desired compression method for the A string containing the desired compression method for the
file. (valid only with libtiff installed) Valid compression file. (valid only with libtiff installed) Valid compression
methods are: ``None``, ``"tiff_ccitt"``, ``"group3"``, methods are: :data:`None`, ``"tiff_ccitt"``, ``"group3"``,
``"group4"``, ``"tiff_jpeg"``, ``"tiff_adobe_deflate"``, ``"group4"``, ``"tiff_jpeg"``, ``"tiff_adobe_deflate"``,
``"tiff_thunderscan"``, ``"tiff_deflate"``, ``"tiff_sgilog"``, ``"tiff_thunderscan"``, ``"tiff_deflate"``, ``"tiff_sgilog"``,
``"tiff_sgilog24"``, ``"tiff_raw_16"`` ``"tiff_sgilog24"``, ``"tiff_raw_16"``
@ -1021,7 +1025,7 @@ FLI, FLC
Pillow reads Autodesk FLI and FLC animations. Pillow reads Autodesk FLI and FLC animations.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**duration** **duration**
@ -1054,7 +1058,7 @@ GBR
The GBR decoder reads GIMP brush files, version 1 and 2. The GBR decoder reads GIMP brush files, version 1 and 2.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**comment** **comment**
@ -1069,7 +1073,7 @@ GD
Pillow reads uncompressed GD2 files. Note that you must use Pillow reads uncompressed GD2 files. Note that you must use
:py:func:`PIL.GdImageFile.open` to read such a file. :py:func:`PIL.GdImageFile.open` to read such a file.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**transparency** **transparency**
@ -1185,7 +1189,7 @@ XPM
Pillow reads X pixmap files (mode ``P``) with 256 colors or less. Pillow reads X pixmap files (mode ``P``) with 256 colors or less.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**transparency** **transparency**

View File

@ -406,13 +406,13 @@ Using the ImageSequence Iterator class
# ...do something to frame... # ...do something to frame...
Postscript printing PostScript printing
------------------- -------------------
The Python Imaging Library includes functions to print images, text and The Python Imaging Library includes functions to print images, text and
graphics on Postscript printers. Heres a simple example: graphics on PostScript printers. Heres a simple example:
Drawing Postscript Drawing PostScript
^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^
:: ::
@ -453,8 +453,8 @@ If everything goes well, the result is an :py:class:`PIL.Image.Image` object.
Otherwise, an :exc:`OSError` exception is raised. Otherwise, an :exc:`OSError` exception is raised.
You can use a file-like object instead of the filename. The object must You can use a file-like object instead of the filename. The object must
implement :py:meth:`~file.read`, :py:meth:`~file.seek` and implement ``file.read``, ``file.seek`` and ``file.tell`` methods,
:py:meth:`~file.tell` methods, and be opened in binary mode. and be opened in binary mode.
Reading from an open file Reading from an open file
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -3,9 +3,9 @@
Writing Your Own Image Plugin Writing Your Own Image Plugin
============================= =============================
The Pillow uses a plug-in model which allows you to add your own Pillow uses a plugin model which allows you to add your own
decoders to the library, without any changes to the library decoders to the library, without any changes to the library
itself. Such plug-ins usually have names like itself. Such plugins usually have names like
:file:`XxxImagePlugin.py`, where ``Xxx`` is a unique format name :file:`XxxImagePlugin.py`, where ``Xxx`` is a unique format name
(usually an abbreviation). (usually an abbreviation).
@ -14,7 +14,7 @@ itself. Such plug-ins usually have names like
:file:`ImagePlugin.py`. You will need to import your :file:`ImagePlugin.py`. You will need to import your
image plugin manually. image plugin manually.
Pillow decodes files in 2 stages: Pillow decodes files in two stages:
1. It loops over the available image plugins in the loaded order, and 1. It loops over the available image plugins in the loaded order, and
calls the plugin's ``_accept`` function with the first 16 bytes of calls the plugin's ``_accept`` function with the first 16 bytes of
@ -26,24 +26,24 @@ Pillow decodes files in 2 stages:
called, which sets up a decoder for each tile and feeds the data to called, which sets up a decoder for each tile and feeds the data to
it. it.
An image plug-in should contain a format handler derived from the An image plugin should contain a format handler derived from the
:py:class:`PIL.ImageFile.ImageFile` base class. This class should :py:class:`PIL.ImageFile.ImageFile` base class. This class should
provide an :py:meth:`_open` method, which reads the file header and provide an ``_open`` method, which reads the file header and
sets up at least the :py:attr:`~PIL.Image.Image.mode` and sets up at least the :py:attr:`~PIL.Image.Image.mode` and
:py:attr:`~PIL.Image.Image.size` attributes. To be able to load the :py:attr:`~PIL.Image.Image.size` attributes. To be able to load the
file, the method must also create a list of :py:attr:`tile` file, the method must also create a list of ``tile`` descriptors,
descriptors, which contain a decoder name, extents of the tile, and which contain a decoder name, extents of the tile, and
any decoder-specific data. The format handler class must be explicitly any decoder-specific data. The format handler class must be explicitly
registered, via a call to the :py:mod:`~PIL.Image` module. registered, via a call to the :py:mod:`~PIL.Image` module.
.. note:: For performance reasons, it is important that the .. note:: For performance reasons, it is important that the
:py:meth:`_open` method quickly rejects files that do not have the ``_open`` method quickly rejects files that do not have the
appropriate contents. appropriate contents.
Example Example
------- -------
The following plug-in supports a simple format, which has a 128-byte header The following plugin supports a simple format, which has a 128-byte header
consisting of the words “SPAM” followed by the width, height, and pixel size in consisting of the words “SPAM” followed by the width, height, and pixel size in
bits. The header fields are separated by spaces. The image data follows bits. The header fields are separated by spaces. The image data follows
directly after the header, and can be either bi-level, greyscale, or 24-bit directly after the header, and can be either bi-level, greyscale, or 24-bit
@ -82,14 +82,14 @@ true color.
raise SyntaxError("unknown number of bits") raise SyntaxError("unknown number of bits")
# data descriptor # data descriptor
self.tile = [ self.tile = [("raw", (0, 0) + self.size, 128, (self.mode, 0, 1))]
("raw", (0, 0) + self.size, 128, (self.mode, 0, 1))
]
Image.register_open(SpamImageFile.format, SpamImageFile, _accept) Image.register_open(SpamImageFile.format, SpamImageFile, _accept)
Image.register_extension(SpamImageFile.format, ".spam") Image.register_extension(SpamImageFile.format, ".spam")
Image.register_extension(SpamImageFile.format, ".spa") # dos version Image.register_extension(SpamImageFile.format, ".spa") # DOS version
The format handler must always set the The format handler must always set the
:py:attr:`~PIL.Image.Image.size` and :py:attr:`~PIL.Image.Image.mode` :py:attr:`~PIL.Image.Image.size` and :py:attr:`~PIL.Image.Image.mode`
@ -103,10 +103,10 @@ Note that the image plugin must be explicitly registered using
:py:func:`PIL.Image.register_open`. Although not required, it is also a good :py:func:`PIL.Image.register_open`. Although not required, it is also a good
idea to register any extensions used by this format. idea to register any extensions used by this format.
The :py:attr:`tile` attribute The ``tile`` attribute
----------------------------- ----------------------
To be able to read the file as well as just identifying it, the :py:attr:`tile` To be able to read the file as well as just identifying it, the ``tile``
attribute must also be set. This attribute consists of a list of tile attribute must also be set. This attribute consists of a list of tile
descriptors, where each descriptor specifies how data should be loaded to a descriptors, where each descriptor specifies how data should be loaded to a
given region in the image. In most cases, only a single descriptor is used, given region in the image. In most cases, only a single descriptor is used,
@ -132,9 +132,9 @@ The fields are used as follows:
**parameters** **parameters**
Parameters to the decoder. The contents of this field depends on the Parameters to the decoder. The contents of this field depends on the
decoder specified by the first field in the tile descriptor tuple. If the decoder specified by the first field in the tile descriptor tuple. If the
decoder doesnt need any parameters, use None for this field. decoder doesnt need any parameters, use :data:`None` for this field.
Note that the :py:attr:`tile` attribute contains a list of tile descriptors, Note that the ``tile`` attribute contains a list of tile descriptors,
not just a single descriptor. not just a single descriptor.
Decoders Decoders
@ -175,7 +175,7 @@ The fields are used as follows:
The **raw mode** field is used to determine how the data should be unpacked to The **raw mode** field is used to determine how the data should be unpacked to
match PILs internal pixel layout. PIL supports a large set of raw modes; for a match PILs internal pixel layout. PIL supports a large set of raw modes; for a
complete list, see the table in the :py:mod:`Unpack.c` module. The following complete list, see the table in the :file:`Unpack.c` module. The following
table describes some commonly used **raw modes**: table describes some commonly used **raw modes**:
+-----------+-----------------------------------------------------------------+ +-----------+-----------------------------------------------------------------+
@ -211,7 +211,7 @@ Note that for the most common cases, the raw mode is simply the same as the mode
The Python Imaging Library supports many other decoders, including JPEG, PNG, The Python Imaging Library supports many other decoders, including JPEG, PNG,
and PackBits. For details, see the :file:`decode.c` source file, and the and PackBits. For details, see the :file:`decode.c` source file, and the
standard plug-in implementations provided with the library. standard plugin implementations provided with the library.
Decoding floating point data Decoding floating point data
---------------------------- ----------------------------

View File

@ -16,25 +16,27 @@ Notes
.. note:: Pillow is supported on the following Python versions .. note:: Pillow is supported on the following Python versions
+--------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|**Python** |**3.8**|**3.7**|**3.6**|**3.5**|**3.4**|**3.3**|**3.2**|**2.7**|**2.6**|**2.5**|**2.4**| | **Python** |**3.9**|**3.8**|**3.7**|**3.6**|**3.5**|**3.4**|**3.3**|**3.2**|**2.7**|**2.6**|**2.5**|**2.4**|
+--------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|Pillow >= 7 | Yes | Yes | Yes | Yes | | | | | | | | | Pillow >= 8.0 | Yes | Yes | Yes | Yes | | | | | | | | |
+--------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|Pillow 6.2.1 - 6.2.2| Yes | Yes | Yes | Yes | | | | Yes | | | | | Pillow 7.0 - 7.2 | | Yes | Yes | Yes | Yes | | | | | | | |
+--------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|Pillow 6.0 - 6.2.0 | | Yes | Yes | Yes | | | | Yes | | | | | Pillow 6.2.1 - 6.2.2 | | Yes | Yes | Yes | Yes | | | | Yes | | | |
+--------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|Pillow 5.2 - 5.4 | | Yes | Yes | Yes | Yes | | | Yes | | | | | Pillow 6.0 - 6.2.0 | | | Yes | Yes | Yes | | | | Yes | | | |
+--------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|Pillow 5.0 - 5.1 | | | Yes | Yes | Yes | | | Yes | | | | | Pillow 5.2 - 5.4 | | | Yes | Yes | Yes | Yes | | | Yes | | | |
+--------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|Pillow 4 | | | Yes | Yes | Yes | Yes | | Yes | | | | | Pillow 5.0 - 5.1 | | | | Yes | Yes | Yes | | | Yes | | | |
+--------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|Pillow 2 - 3 | | | | Yes | Yes | Yes | Yes | Yes | Yes | | | | Pillow 4 | | | | Yes | Yes | Yes | Yes | | Yes | | | |
+--------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|Pillow < 2 | | | | | | | | Yes | Yes | Yes | Yes | | Pillow 2 - 3 | | | | | Yes | Yes | Yes | Yes | Yes | Yes | | |
+--------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ +----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Pillow < 2 | | | | | | | | | Yes | Yes | Yes | Yes |
+----------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
Basic Installation Basic Installation
------------------ ------------------
@ -393,29 +395,27 @@ These platforms are built and tested for every change.
+----------------------------------+--------------------------+-----------------------+ +----------------------------------+--------------------------+-----------------------+
| CentOS 8 | 3.6 |x86-64 | | CentOS 8 | 3.6 |x86-64 |
+----------------------------------+--------------------------+-----------------------+ +----------------------------------+--------------------------+-----------------------+
| Debian 9 Stretch | 3.5 |x86 |
+----------------------------------+--------------------------+-----------------------+
| Debian 10 Buster | 3.7 |x86 | | Debian 10 Buster | 3.7 |x86 |
+----------------------------------+--------------------------+-----------------------+ +----------------------------------+--------------------------+-----------------------+
| Fedora 31 | 3.7 |x86-64 | | Fedora 31 | 3.7 |x86-64 |
+----------------------------------+--------------------------+-----------------------+ +----------------------------------+--------------------------+-----------------------+
| Fedora 32 | 3.8 |x86-64 | | Fedora 32 | 3.8 |x86-64 |
+----------------------------------+--------------------------+-----------------------+ +----------------------------------+--------------------------+-----------------------+
| macOS 10.15 Catalina | 3.5, 3.6, 3.7, 3.8, PyPy3|x86-64 | | macOS 10.15 Catalina | 3.6, 3.7, 3.8, PyPy3 |x86-64 |
+----------------------------------+--------------------------+-----------------------+ +----------------------------------+--------------------------+-----------------------+
| Ubuntu Linux 16.04 LTS | 3.5, 3.6, 3.7, 3.8, PyPy3|x86-64 | | Ubuntu Linux 16.04 LTS (Xenial) | 3.6, 3.7, 3.8, PyPy3 |x86-64 |
+----------------------------------+--------------------------+-----------------------+ +----------------------------------+--------------------------+-----------------------+
| Ubuntu Linux 18.04 LTS | 3.6 |x86-64 | | Ubuntu Linux 18.04 LTS (Bionic) | 3.6, 3.7, 3.8, PyPy3 |x86-64 |
+----------------------------------+--------------------------+-----------------------+ +----------------------------------+--------------------------+-----------------------+
| Ubuntu Linux 20.04 LTS | 3.8 |x86-64 | | Ubuntu Linux 20.04 LTS (Focal) | 3.8 |x86-64 |
+----------------------------------+--------------------------+-----------------------+ +----------------------------------+--------------------------+-----------------------+
| Windows Server 2016 | 3.8 |x86 | | Windows Server 2016 | 3.8 |x86 |
| +--------------------------+-----------------------+ | +--------------------------+-----------------------+
| | 3.5 |x86-64 | | | 3.6 |x86-64 |
| +--------------------------+-----------------------+ | +--------------------------+-----------------------+
| | 3.7/MinGW |x86 | | | 3.7/MinGW |x86 |
+----------------------------------+--------------------------+-----------------------+ +----------------------------------+--------------------------+-----------------------+
| Windows Server 2019 | 3.5, 3.6, 3.7, 3.8 |x86, x86-64 | | Windows Server 2019 | 3.6, 3.7, 3.8 |x86, x86-64 |
| +--------------------------+-----------------------+ | +--------------------------+-----------------------+
| | PyPy3 |x86 | | | PyPy3 |x86 |
+----------------------------------+--------------------------+-----------------------+ +----------------------------------+--------------------------+-----------------------+
@ -434,9 +434,11 @@ These platforms have been reported to work at the versions mentioned.
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+
|**Operating system** |**Tested Python versions** |**Latest tested Pillow version**|**Tested processors** | |**Operating system** |**Tested Python versions** |**Latest tested Pillow version**|**Tested processors** |
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+
| macOS 10.15 Catalina | 3.5, 3.6, 3.7, 3.8 | 7.1.2 |x86-64 | | macOS 10.15 Catalina | 3.5, 3.6, 3.7, 3.8 | 7.2.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+
| macOS 10.14 Mojave | 2.7, 3.5, 3.6, 3.7 | 6.0.0 |x86-64 | | macOS 10.14 Mojave | 3.5, 3.6, 3.7, 3.8 | 7.2.0 |x86-64 |
| +------------------------------+--------------------------------+ +
| | 2.7 | 6.0.0 | |
| +------------------------------+--------------------------------+ + | +------------------------------+--------------------------------+ +
| | 3.4 | 5.4.1 | | | | 3.4 | 5.4.1 | |
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+
@ -458,14 +460,14 @@ These platforms have been reported to work at the versions mentioned.
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+
| Fedora 23 | 2.7, 3.4 | 3.1.0 |x86-64 | | Fedora 23 | 2.7, 3.4 | 3.1.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+
| Ubuntu Linux 12.04 LTS | 2.6, 3.2, 3.3, 3.4, 3.5 | 3.4.1 |x86,x86-64 | | Ubuntu Linux 12.04 LTS (Precise) | 2.6, 3.2, 3.3, 3.4, 3.5 | 3.4.1 |x86,x86-64 |
| | PyPy5.3.1, PyPy3 v2.4.0 | | | | | PyPy5.3.1, PyPy3 v2.4.0 | | |
| +------------------------------+--------------------------------+-----------------------+ | +------------------------------+--------------------------------+-----------------------+
| | 2.7 | 4.3.0 |x86-64 | | | 2.7 | 4.3.0 |x86-64 |
| +------------------------------+--------------------------------+-----------------------+ | +------------------------------+--------------------------------+-----------------------+
| | 2.7, 3.2 | 3.4.1 |ppc | | | 2.7, 3.2 | 3.4.1 |ppc |
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+
| Ubuntu Linux 10.04 LTS | 2.6 | 2.3.0 |x86,x86-64 | | Ubuntu Linux 10.04 LTS (Lucid) | 2.6 | 2.3.0 |x86,x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+
| Debian 8.2 Jessie | 2.7, 3.4 | 3.1.0 |x86-64 | | Debian 8.2 Jessie | 2.7, 3.4 | 3.1.0 |x86-64 |
+----------------------------------+------------------------------+--------------------------------+-----------------------+ +----------------------------------+------------------------------+--------------------------------+-----------------------+

View File

@ -19,7 +19,8 @@ to this::
from PIL import Image from PIL import Image
The :py:mod:`_imaging` module has been moved. You can now import it like this:: The :py:mod:`PIL._imaging` module has been moved to :py:mod:`PIL.Image.core`.
You can now import it like this::
from PIL.Image import core as _imaging from PIL.Image import core as _imaging

View File

@ -1,13 +1,14 @@
.. py:module:: PIL.ExifTags .. py:module:: PIL.ExifTags
.. py:currentmodule:: PIL.ExifTags .. py:currentmodule:: PIL.ExifTags
:py:mod:`ExifTags` Module :py:mod:`~PIL.ExifTags` Module
========================== ==============================
The :py:mod:`ExifTags` module exposes two dictionaries which The :py:mod:`~PIL.ExifTags` module exposes two dictionaries which
provide constants and clear-text names for various well-known EXIF tags. provide constants and clear-text names for various well-known EXIF tags.
.. py:class:: PIL.ExifTags.TAGS .. py:data:: TAGS
:type: dict
The TAG dictionary maps 16-bit integer EXIF tag enumerations to The TAG dictionary maps 16-bit integer EXIF tag enumerations to
descriptive string names. For instance: descriptive string names. For instance:
@ -16,7 +17,8 @@ provide constants and clear-text names for various well-known EXIF tags.
>>> TAGS[0x010e] >>> TAGS[0x010e]
'ImageDescription' 'ImageDescription'
.. py:class:: PIL.ExifTags.GPSTAGS .. py:data:: GPSTAGS
:type: dict
The GPSTAGS dictionary maps 8-bit integer EXIF gps enumerations to The GPSTAGS dictionary maps 8-bit integer EXIF gps enumerations to
descriptive string names. For instance: descriptive string names. For instance:

View File

@ -1,8 +1,8 @@
.. py:module:: PIL.Image .. py:module:: PIL.Image
.. py:currentmodule:: PIL.Image .. py:currentmodule:: PIL.Image
:py:mod:`Image` Module :py:mod:`~PIL.Image` Module
====================== ===========================
The :py:mod:`~PIL.Image` module provides a class with the same name which is The :py:mod:`~PIL.Image` module provides a class with the same name which is
used to represent a PIL image. The module also provides a number of factory used to represent a PIL image. The module also provides a number of factory
@ -52,11 +52,19 @@ Functions
.. warning:: .. warning::
To protect against potential DOS attacks caused by "`decompression bombs`_" (i.e. malicious files To protect against potential DOS attacks caused by "`decompression bombs`_" (i.e. malicious files
which decompress into a huge amount of data and are designed to crash or cause disruption by using up which decompress into a huge amount of data and are designed to crash or cause disruption by using up
a lot of memory), Pillow will issue a ``DecompressionBombWarning`` if the image is over a certain a lot of memory), Pillow will issue a ``DecompressionBombWarning`` if the number of pixels in an
limit. If desired, the warning can be turned into an error with image is over a certain limit, :py:data:`PIL.Image.MAX_IMAGE_PIXELS`.
This threshold can be changed by setting :py:data:`PIL.Image.MAX_IMAGE_PIXELS`. It can be disabled
by setting ``Image.MAX_IMAGE_PIXELS = None``.
If desired, the warning can be turned into an error with
``warnings.simplefilter('error', Image.DecompressionBombWarning)`` or suppressed entirely with ``warnings.simplefilter('error', Image.DecompressionBombWarning)`` or suppressed entirely with
``warnings.simplefilter('ignore', Image.DecompressionBombWarning)``. See also `the logging ``warnings.simplefilter('ignore', Image.DecompressionBombWarning)``. See also
documentation`_ to have warnings output to the logging facility instead of stderr. `the logging documentation`_ to have warnings output to the logging facility instead of stderr.
If the number of pixels is greater than twice :py:data:`PIL.Image.MAX_IMAGE_PIXELS`, then a
``DecompressionBombError`` will be raised instead.
.. _decompression bombs: https://en.wikipedia.org/wiki/Zip_bomb .. _decompression bombs: https://en.wikipedia.org/wiki/Zip_bomb
.. _the logging documentation: https://docs.python.org/3/library/logging.html#integration-with-the-warnings-module .. _the logging documentation: https://docs.python.org/3/library/logging.html#integration-with-the-warnings-module
@ -76,9 +84,16 @@ Constructing images
.. autofunction:: new .. autofunction:: new
.. autofunction:: fromarray .. autofunction:: fromarray
.. autofunction:: frombytes .. autofunction:: frombytes
.. autofunction:: fromstring
.. autofunction:: frombuffer .. autofunction:: frombuffer
Generating images
^^^^^^^^^^^^^^^^^
.. autofunction:: effect_mandelbrot
.. autofunction:: effect_noise
.. autofunction:: linear_gradient
.. autofunction:: radial_gradient
Registering plugins Registering plugins
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
@ -88,12 +103,14 @@ Registering plugins
ignore them. ignore them.
.. autofunction:: register_open .. autofunction:: register_open
.. autofunction:: register_decoder
.. autofunction:: register_mime .. autofunction:: register_mime
.. autofunction:: register_save .. autofunction:: register_save
.. autofunction:: register_encoder .. autofunction:: register_save_all
.. autofunction:: register_extension .. autofunction:: register_extension
.. autofunction:: register_extensions
.. autofunction:: registered_extensions
.. autofunction:: register_decoder
.. autofunction:: register_encoder
The Image Class The Image Class
--------------- ---------------
@ -140,6 +157,8 @@ This crops the input image with the provided coordinates:
.. automethod:: PIL.Image.Image.draft .. automethod:: PIL.Image.Image.draft
.. automethod:: PIL.Image.Image.effect_spread
.. automethod:: PIL.Image.Image.entropy
.. automethod:: PIL.Image.Image.filter .. automethod:: PIL.Image.Image.filter
This blurs the input image using a filter from the ``ImageFilter`` module: This blurs the input image using a filter from the ``ImageFilter`` module:
@ -176,12 +195,14 @@ This helps to get the bounding box coordinates of the input image:
print(im.getbbox()) print(im.getbbox())
# Returns four coordinates in the format (left, upper, right, lower) # Returns four coordinates in the format (left, upper, right, lower)
.. automethod:: PIL.Image.Image.getchannel
.. automethod:: PIL.Image.Image.getcolors .. automethod:: PIL.Image.Image.getcolors
.. automethod:: PIL.Image.Image.getdata .. automethod:: PIL.Image.Image.getdata
.. automethod:: PIL.Image.Image.getextrema
.. automethod:: PIL.Image.Image.getexif .. automethod:: PIL.Image.Image.getexif
.. automethod:: PIL.Image.Image.getextrema
.. automethod:: PIL.Image.Image.getpalette .. automethod:: PIL.Image.Image.getpalette
.. automethod:: PIL.Image.Image.getpixel .. automethod:: PIL.Image.Image.getpixel
.. automethod:: PIL.Image.Image.getprojection
.. automethod:: PIL.Image.Image.histogram .. automethod:: PIL.Image.Image.histogram
.. automethod:: PIL.Image.Image.offset .. automethod:: PIL.Image.Image.offset
.. automethod:: PIL.Image.Image.paste .. automethod:: PIL.Image.Image.paste
@ -191,6 +212,8 @@ This helps to get the bounding box coordinates of the input image:
.. automethod:: PIL.Image.Image.putpalette .. automethod:: PIL.Image.Image.putpalette
.. automethod:: PIL.Image.Image.putpixel .. automethod:: PIL.Image.Image.putpixel
.. automethod:: PIL.Image.Image.quantize .. automethod:: PIL.Image.Image.quantize
.. automethod:: PIL.Image.Image.reduce
.. automethod:: PIL.Image.Image.remap_palette
.. automethod:: PIL.Image.Image.resize .. automethod:: PIL.Image.Image.resize
This resizes the given image from ``(width, height)`` to ``(width/2, height/2)``: This resizes the given image from ``(width, height)`` to ``(width/2, height/2)``:
@ -205,7 +228,6 @@ This resizes the given image from ``(width, height)`` to ``(width/2, height/2)``
(width, height) = (im.width // 2, im.height // 2) (width, height) = (im.width // 2, im.height // 2)
im_resized = im.resize((width, height)) im_resized = im.resize((width, height))
.. automethod:: PIL.Image.Image.remap_palette
.. automethod:: PIL.Image.Image.rotate .. automethod:: PIL.Image.Image.rotate
This rotates the input image by ``theta`` degrees counter clockwise: This rotates the input image by ``theta`` degrees counter clockwise:
@ -225,7 +247,6 @@ This rotates the input image by ``theta`` degrees counter clockwise:
.. automethod:: PIL.Image.Image.seek .. automethod:: PIL.Image.Image.seek
.. automethod:: PIL.Image.Image.show .. automethod:: PIL.Image.Image.show
.. automethod:: PIL.Image.Image.split .. automethod:: PIL.Image.Image.split
.. automethod:: PIL.Image.Image.getchannel
.. automethod:: PIL.Image.Image.tell .. automethod:: PIL.Image.Image.tell
.. automethod:: PIL.Image.Image.thumbnail .. automethod:: PIL.Image.Image.thumbnail
.. automethod:: PIL.Image.Image.tobitmap .. automethod:: PIL.Image.Image.tobitmap
@ -234,7 +255,7 @@ This rotates the input image by ``theta`` degrees counter clockwise:
.. automethod:: PIL.Image.Image.transform .. automethod:: PIL.Image.Image.transform
.. automethod:: PIL.Image.Image.transpose .. automethod:: PIL.Image.Image.transpose
This flips the input image by using the ``Image.FLIP_LEFT_RIGHT`` method. This flips the input image by using the :data:`FLIP_LEFT_RIGHT` method.
.. code-block:: python .. code-block:: python
@ -255,62 +276,56 @@ This flips the input image by using the ``Image.FLIP_LEFT_RIGHT`` method.
.. automethod:: PIL.Image.Image.load .. automethod:: PIL.Image.Image.load
.. automethod:: PIL.Image.Image.close .. automethod:: PIL.Image.Image.close
Attributes Image Attributes
---------- ----------------
Instances of the :py:class:`Image` class have the following attributes: Instances of the :py:class:`Image` class have the following attributes:
.. py:attribute:: filename .. py:attribute:: Image.filename
:type: str
The filename or path of the source file. Only images created with the The filename or path of the source file. Only images created with the
factory function ``open`` have a filename attribute. If the input is a factory function ``open`` have a filename attribute. If the input is a
file like object, the filename attribute is set to an empty string. file like object, the filename attribute is set to an empty string.
:type: :py:class:`string` .. py:attribute:: Image.format
:type: Optional[str]
.. py:attribute:: format
The file format of the source file. For images created by the library The file format of the source file. For images created by the library
itself (via a factory function, or by running a method on an existing itself (via a factory function, or by running a method on an existing
image), this attribute is set to ``None``. image), this attribute is set to :data:`None`.
:type: :py:class:`string` or ``None`` .. py:attribute:: Image.mode
:type: str
.. py:attribute:: mode
Image mode. This is a string specifying the pixel format used by the image. Image mode. This is a string specifying the pixel format used by the image.
Typical values are “1”, “L”, “RGB”, or “CMYK.” See Typical values are “1”, “L”, “RGB”, or “CMYK.” See
:ref:`concept-modes` for a full list. :ref:`concept-modes` for a full list.
:type: :py:class:`string` .. py:attribute:: Image.size
:type: tuple[int]
.. py:attribute:: size
Image size, in pixels. The size is given as a 2-tuple (width, height). Image size, in pixels. The size is given as a 2-tuple (width, height).
:type: ``(width, height)`` .. py:attribute:: Image.width
:type: int
.. py:attribute:: width
Image width, in pixels. Image width, in pixels.
:type: :py:class:`int` .. py:attribute:: Image.height
:type: int
.. py:attribute:: height
Image height, in pixels. Image height, in pixels.
:type: :py:class:`int` .. py:attribute:: Image.palette
:type: Optional[PIL.ImagePalette.ImagePalette]
.. py:attribute:: palette
Colour palette table, if any. If mode is "P" or "PA", this should be an Colour palette table, if any. If mode is "P" or "PA", this should be an
instance of the :py:class:`~PIL.ImagePalette.ImagePalette` class. instance of the :py:class:`~PIL.ImagePalette.ImagePalette` class.
Otherwise, it should be set to ``None``. Otherwise, it should be set to :data:`None`.
:type: :py:class:`~PIL.ImagePalette.ImagePalette` or ``None`` .. py:attribute:: Image.info
:type: dict
.. py:attribute:: info
A dictionary holding data associated with the image. This dictionary is A dictionary holding data associated with the image. This dictionary is
used by file handlers to pass on various non-image information read from used by file handlers to pass on various non-image information read from
@ -323,4 +338,177 @@ Instances of the :py:class:`Image` class have the following attributes:
Unless noted elsewhere, this dictionary does not affect saving files. Unless noted elsewhere, this dictionary does not affect saving files.
:type: :py:class:`dict` .. py:attribute:: Image.is_animated
:type: bool
``True`` if this image has more than one frame, or ``False`` otherwise.
This attribute is only defined by image plugins that support animated images.
Plugins may leave this attribute undefined if they don't support loading
animated images, even if the given format supports animated images.
Given that this attribute is not present for all images use
``getattr(image, "is_animated", False)`` to check if Pillow is aware of multiple
frames in an image regardless of its format.
.. seealso:: :attr:`~Image.n_frames`, :func:`~Image.seek` and :func:`~Image.tell`
.. py:attribute:: Image.n_frames
:type: int
The number of frames in this image.
This attribute is only defined by image plugins that support animated images.
Plugins may leave this attribute undefined if they don't support loading
animated images, even if the given format supports animated images.
Given that this attribute is not present for all images use
``getattr(image, "n_frames", 1)`` to check the number of frames that Pillow is
aware of in an image regardless of its format.
.. seealso:: :attr:`~Image.is_animated`, :func:`~Image.seek` and :func:`~Image.tell`
Classes
-------
.. autoclass:: PIL.Image.Exif
:members:
:undoc-members:
:show-inheritance:
.. autoclass:: PIL.Image.ImagePointHandler
.. autoclass:: PIL.Image.ImageTransformHandler
Constants
---------
.. data:: NONE
.. data:: MAX_IMAGE_PIXELS
Set to 89,478,485, approximately 0.25GB for a 24-bit (3 bpp) image.
See :py:meth:`~PIL.Image.open` for more information about how this is used.
Transpose methods
^^^^^^^^^^^^^^^^^
Used to specify the :meth:`Image.transpose` method to use.
.. data:: FLIP_LEFT_RIGHT
.. data:: FLIP_TOP_BOTTOM
.. data:: ROTATE_90
.. data:: ROTATE_180
.. data:: ROTATE_270
.. data:: TRANSPOSE
.. data:: TRANSVERSE
Transform methods
^^^^^^^^^^^^^^^^^
Used to specify the :meth:`Image.transform` method to use.
.. data:: AFFINE
Affine transform
.. data:: EXTENT
Cut out a rectangular subregion
.. data:: PERSPECTIVE
Perspective transform
.. data:: QUAD
Map a quadrilateral to a rectangle
.. data:: MESH
Map a number of source quadrilaterals in one operation
Resampling filters
^^^^^^^^^^^^^^^^^^
See :ref:`concept-filters` for details.
.. data:: NEAREST
:noindex:
.. data:: BOX
:noindex:
.. data:: BILINEAR
:noindex:
.. data:: HAMMING
:noindex:
.. data:: BICUBIC
:noindex:
.. data:: LANCZOS
:noindex:
Some filters are also available under the following names for backwards compatibility:
.. data:: NONE
:noindex:
:value: NEAREST
.. data:: LINEAR
:value: BILINEAR
.. data:: CUBIC
:value: BICUBIC
.. data:: ANTIALIAS
:value: LANCZOS
Dither modes
^^^^^^^^^^^^
Used to specify the dithering method to use for the
:meth:`~Image.convert` and :meth:`~Image.quantize` methods.
.. data:: NONE
:noindex:
No dither
.. comment: (not implemented)
.. data:: ORDERED
.. data:: RASTERIZE
.. data:: FLOYDSTEINBERG
Floyd-Steinberg dither
Palettes
^^^^^^^^
Used to specify the pallete to use for the :meth:`~Image.convert` method.
.. data:: WEB
.. data:: ADAPTIVE
Quantization methods
^^^^^^^^^^^^^^^^^^^^
Used to specify the quantization method to use for the :meth:`~Image.quantize` method.
.. data:: MEDIANCUT
Median cut
.. data:: MAXCOVERAGE
Maximum coverage
.. data:: FASTOCTREE
Fast octree
.. data:: LIBIMAGEQUANT
libimagequant
Check support using :py:func:`PIL.features.check_feature`
with ``feature="libimagequant"``.
.. comment: These are not referenced anywhere?
Categories
^^^^^^^^^^
.. data:: NORMAL
.. data:: SEQUENCE
.. data:: CONTAINER

View File

@ -1,15 +1,15 @@
.. py:module:: PIL.ImageChops .. py:module:: PIL.ImageChops
.. py:currentmodule:: PIL.ImageChops .. py:currentmodule:: PIL.ImageChops
:py:mod:`ImageChops` ("Channel Operations") Module :py:mod:`~PIL.ImageChops` ("Channel Operations") Module
================================================== =======================================================
The :py:mod:`ImageChops` module contains a number of arithmetical image The :py:mod:`~PIL.ImageChops` module contains a number of arithmetical image
operations, called channel operations (“chops”). These can be used for various operations, called channel operations (“chops”). These can be used for various
purposes, including special effects, image compositions, algorithmic painting, purposes, including special effects, image compositions, algorithmic painting,
and more. and more.
For more pre-made operations, see :py:mod:`ImageOps`. For more pre-made operations, see :py:mod:`~PIL.ImageOps`.
At this time, most channel operations are only implemented for 8-bit images At this time, most channel operations are only implemented for 8-bit images
(e.g. “L” and “RGB”). (e.g. “L” and “RGB”).

View File

@ -1,16 +1,37 @@
.. py:module:: PIL.ImageCms .. py:module:: PIL.ImageCms
.. py:currentmodule:: PIL.ImageCms .. py:currentmodule:: PIL.ImageCms
:py:mod:`ImageCms` Module :py:mod:`~PIL.ImageCms` Module
========================= ==============================
The :py:mod:`ImageCms` module provides color profile management The :py:mod:`~PIL.ImageCms` module provides color profile management
support using the LittleCMS2 color management engine, based on Kevin support using the LittleCMS2 color management engine, based on Kevin
Cazabon's PyCMS library. Cazabon's PyCMS library.
.. automodule:: PIL.ImageCms .. autoclass:: ImageCmsTransform
:members: .. autoexception:: PyCMSError
:noindex:
Functions
---------
.. autofunction:: applyTransform
.. autofunction:: buildProofTransform
.. autofunction:: buildProofTransformFromOpenProfiles
.. autofunction:: buildTransform
.. autofunction:: buildTransformFromOpenProfiles
.. autofunction:: createProfile
.. autofunction:: getDefaultIntent
.. autofunction:: getOpenProfile
.. autofunction:: getProfileCopyright
.. autofunction:: getProfileDescription
.. autofunction:: getProfileInfo
.. autofunction:: getProfileManufacturer
.. autofunction:: getProfileModel
.. autofunction:: getProfileName
.. autofunction:: get_display_profile
.. autofunction:: isIntentSupported
.. autofunction:: profileToProfile
.. autofunction:: versions
CmsProfile CmsProfile
---------- ----------
@ -25,87 +46,73 @@ can be easily displayed in a chromaticity diagram, for example).
.. py:class:: CmsProfile .. py:class:: CmsProfile
.. py:attribute:: creation_date .. py:attribute:: creation_date
:type: Optional[datetime.datetime]
Date and time this profile was first created (see 7.2.1 of ICC.1:2010). Date and time this profile was first created (see 7.2.1 of ICC.1:2010).
:type: :py:class:`datetime.datetime` or ``None``
.. py:attribute:: version .. py:attribute:: version
:type: float
The version number of the ICC standard that this profile follows The version number of the ICC standard that this profile follows
(e.g. ``2.0``). (e.g. ``2.0``).
:type: :py:class:`float`
.. py:attribute:: icc_version .. py:attribute:: icc_version
:type: int
Same as ``version``, but in encoded format (see 7.2.4 of ICC.1:2010). Same as ``version``, but in encoded format (see 7.2.4 of ICC.1:2010).
.. py:attribute:: device_class .. py:attribute:: device_class
:type: str
4-character string identifying the profile class. One of 4-character string identifying the profile class. One of
``scnr``, ``mntr``, ``prtr``, ``link``, ``spac``, ``abst``, ``scnr``, ``mntr``, ``prtr``, ``link``, ``spac``, ``abst``,
``nmcl`` (see 7.2.5 of ICC.1:2010 for details). ``nmcl`` (see 7.2.5 of ICC.1:2010 for details).
:type: :py:class:`string`
.. py:attribute:: xcolor_space .. py:attribute:: xcolor_space
:type: str
4-character string (padded with whitespace) identifying the color 4-character string (padded with whitespace) identifying the color
space, e.g. ``XYZ␣``, ``RGB␣`` or ``CMYK`` (see 7.2.6 of space, e.g. ``XYZ␣``, ``RGB␣`` or ``CMYK`` (see 7.2.6 of
ICC.1:2010 for details). ICC.1:2010 for details).
Note that the deprecated attribute ``color_space`` contains an
interpreted (non-padded) variant of this (but can be empty on
unknown input).
:type: :py:class:`string`
.. py:attribute:: connection_space .. py:attribute:: connection_space
:type: str
4-character string (padded with whitespace) identifying the color 4-character string (padded with whitespace) identifying the color
space on the B-side of the transform (see 7.2.7 of ICC.1:2010 for space on the B-side of the transform (see 7.2.7 of ICC.1:2010 for
details). details).
Note that the deprecated attribute ``pcs`` contains an interpreted
(non-padded) variant of this (but can be empty on unknown input).
:type: :py:class:`string`
.. py:attribute:: header_flags .. py:attribute:: header_flags
:type: int
The encoded header flags of the profile (see 7.2.11 of ICC.1:2010 The encoded header flags of the profile (see 7.2.11 of ICC.1:2010
for details). for details).
:type: :py:class:`int`
.. py:attribute:: header_manufacturer .. py:attribute:: header_manufacturer
:type: str
4-character string (padded with whitespace) identifying the device 4-character string (padded with whitespace) identifying the device
manufacturer, which shall match the signature contained in the manufacturer, which shall match the signature contained in the
appropriate section of the ICC signature registry found at appropriate section of the ICC signature registry found at
www.color.org (see 7.2.12 of ICC.1:2010). www.color.org (see 7.2.12 of ICC.1:2010).
:type: :py:class:`string`
.. py:attribute:: header_model .. py:attribute:: header_model
:type: str
4-character string (padded with whitespace) identifying the device 4-character string (padded with whitespace) identifying the device
model, which shall match the signature contained in the model, which shall match the signature contained in the
appropriate section of the ICC signature registry found at appropriate section of the ICC signature registry found at
www.color.org (see 7.2.13 of ICC.1:2010). www.color.org (see 7.2.13 of ICC.1:2010).
:type: :py:class:`string`
.. py:attribute:: attributes .. py:attribute:: attributes
:type: int
Flags used to identify attributes unique to the particular device Flags used to identify attributes unique to the particular device
setup for which the profile is applicable (see 7.2.14 of setup for which the profile is applicable (see 7.2.14 of
ICC.1:2010 for details). ICC.1:2010 for details).
:type: :py:class:`int`
.. py:attribute:: rendering_intent .. py:attribute:: rendering_intent
:type: int
The rendering intent to use when combining this profile with The rendering intent to use when combining this profile with
another profile (usually overridden at run-time, but provided here another profile (usually overridden at run-time, but provided here
@ -114,84 +121,82 @@ can be easily displayed in a chromaticity diagram, for example).
One of ``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC``, ``ImageCms.INTENT_PERCEPTUAL``, One of ``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC``, ``ImageCms.INTENT_PERCEPTUAL``,
``ImageCms.INTENT_RELATIVE_COLORIMETRIC`` and ``ImageCms.INTENT_SATURATION``. ``ImageCms.INTENT_RELATIVE_COLORIMETRIC`` and ``ImageCms.INTENT_SATURATION``.
:type: :py:class:`int`
.. py:attribute:: profile_id .. py:attribute:: profile_id
:type: bytes
A sequence of 16 bytes identifying the profile (via a specially A sequence of 16 bytes identifying the profile (via a specially
constructed MD5 sum), or 16 binary zeroes if the profile ID has constructed MD5 sum), or 16 binary zeroes if the profile ID has
not been calculated (see 7.2.18 of ICC.1:2010). not been calculated (see 7.2.18 of ICC.1:2010).
:type: :py:class:`bytes`
.. py:attribute:: copyright .. py:attribute:: copyright
:type: Optional[str]
The text copyright information for the profile (see 9.2.21 of ICC.1:2010). The text copyright information for the profile (see 9.2.21 of ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: manufacturer .. py:attribute:: manufacturer
:type: Optional[str]
The (English) display string for the device manufacturer (see The (English) display string for the device manufacturer (see
9.2.22 of ICC.1:2010). 9.2.22 of ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: model .. py:attribute:: model
:type: Optional[str]
The (English) display string for the device model of the device The (English) display string for the device model of the device
for which this profile is created (see 9.2.23 of ICC.1:2010). for which this profile is created (see 9.2.23 of ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: profile_description .. py:attribute:: profile_description
:type: Optional[str]
The (English) display string for the profile description (see The (English) display string for the profile description (see
9.2.41 of ICC.1:2010). 9.2.41 of ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: target .. py:attribute:: target
:type: Optional[str]
The name of the registered characterization data set, or the The name of the registered characterization data set, or the
measurement data for a characterization target (see 9.2.14 of measurement data for a characterization target (see 9.2.14 of
ICC.1:2010). ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: red_colorant .. py:attribute:: red_colorant
:type: Optional[tuple[tuple[float]]]
The first column in the matrix used in matrix/TRC transforms (see 9.2.44 of ICC.1:2010). The first column in the matrix used in matrix/TRC transforms (see 9.2.44 of ICC.1:2010).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: green_colorant .. py:attribute:: green_colorant
:type: Optional[tuple[tuple[float]]]
The second column in the matrix used in matrix/TRC transforms (see 9.2.30 of ICC.1:2010). The second column in the matrix used in matrix/TRC transforms (see 9.2.30 of ICC.1:2010).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: blue_colorant .. py:attribute:: blue_colorant
:type: Optional[tuple[tuple[float]]]
The third column in the matrix used in matrix/TRC transforms (see 9.2.4 of ICC.1:2010). The third column in the matrix used in matrix/TRC transforms (see 9.2.4 of ICC.1:2010).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: luminance .. py:attribute:: luminance
:type: Optional[tuple[tuple[float]]]
The absolute luminance of emissive devices in candelas per square The absolute luminance of emissive devices in candelas per square
metre as described by the Y channel (see 9.2.32 of ICC.1:2010). metre as described by the Y channel (see 9.2.32 of ICC.1:2010).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: chromaticity .. py:attribute:: chromaticity
:type: Optional[tuple[tuple[float]]]
The data of the phosphor/colorant chromaticity set used (red, The data of the phosphor/colorant chromaticity set used (red,
green and blue channels, see 9.2.16 of ICC.1:2010). green and blue channels, see 9.2.16 of ICC.1:2010).
:type: ``((x, y, Y), (x, y, Y), (x, y, Y))`` or ``None`` The value is in the format ``((x, y, Y), (x, y, Y), (x, y, Y))``, if available.
.. py:attribute:: chromatic_adaption .. py:attribute:: chromatic_adaption
:type: tuple[tuple[float]]
The chromatic adaption matrix converts a color measured using the The chromatic adaption matrix converts a color measured using the
actual illumination conditions and relative to the actual adopted actual illumination conditions and relative to the actual adopted
@ -199,58 +204,52 @@ can be easily displayed in a chromaticity diagram, for example).
complete adaptation from the actual adopted white chromaticity to complete adaptation from the actual adopted white chromaticity to
the PCS adopted white chromaticity (see 9.2.15 of ICC.1:2010). the PCS adopted white chromaticity (see 9.2.15 of ICC.1:2010).
Two matrices are returned, one in (X, Y, Z) space and one in (x, y, Y) space. Two 3-tuples of floats are returned in a 2-tuple,
one in (X, Y, Z) space and one in (x, y, Y) space.
:type: 2-tuple of 3-tuple, the first with (X, Y, Z) and the second with (x, y, Y) values
.. py:attribute:: colorant_table .. py:attribute:: colorant_table
:type: list[str]
This tag identifies the colorants used in the profile by a unique This tag identifies the colorants used in the profile by a unique
name and set of PCSXYZ or PCSLAB values (see 9.2.19 of name and set of PCSXYZ or PCSLAB values (see 9.2.19 of
ICC.1:2010). ICC.1:2010).
:type: list of strings
.. py:attribute:: colorant_table_out .. py:attribute:: colorant_table_out
:type: list[str]
This tag identifies the colorants used in the profile by a unique This tag identifies the colorants used in the profile by a unique
name and set of PCSLAB values (for DeviceLink profiles only, see name and set of PCSLAB values (for DeviceLink profiles only, see
9.2.19 of ICC.1:2010). 9.2.19 of ICC.1:2010).
:type: list of strings
.. py:attribute:: colorimetric_intent .. py:attribute:: colorimetric_intent
:type: Optional[str]
4-character string (padded with whitespace) identifying the image 4-character string (padded with whitespace) identifying the image
state of PCS colorimetry produced using the colorimetric intent state of PCS colorimetry produced using the colorimetric intent
transforms (see 9.2.20 of ICC.1:2010 for details). transforms (see 9.2.20 of ICC.1:2010 for details).
:type: :py:class:`string` or ``None``
.. py:attribute:: perceptual_rendering_intent_gamut .. py:attribute:: perceptual_rendering_intent_gamut
:type: Optional[str]
4-character string (padded with whitespace) identifying the (one) 4-character string (padded with whitespace) identifying the (one)
standard reference medium gamut (see 9.2.37 of ICC.1:2010 for standard reference medium gamut (see 9.2.37 of ICC.1:2010 for
details). details).
:type: :py:class:`string` or ``None``
.. py:attribute:: saturation_rendering_intent_gamut .. py:attribute:: saturation_rendering_intent_gamut
:type: Optional[str]
4-character string (padded with whitespace) identifying the (one) 4-character string (padded with whitespace) identifying the (one)
standard reference medium gamut (see 9.2.37 of ICC.1:2010 for standard reference medium gamut (see 9.2.37 of ICC.1:2010 for
details). details).
:type: :py:class:`string` or ``None``
.. py:attribute:: technology .. py:attribute:: technology
:type: Optional[str]
4-character string (padded with whitespace) identifying the device 4-character string (padded with whitespace) identifying the device
technology (see 9.2.47 of ICC.1:2010 for details). technology (see 9.2.47 of ICC.1:2010 for details).
:type: :py:class:`string` or ``None``
.. py:attribute:: media_black_point .. py:attribute:: media_black_point
:type: Optional[tuple[tuple[float]]]
This tag specifies the media black point and is used for This tag specifies the media black point and is used for
generating absolute colorimetry. generating absolute colorimetry.
@ -258,57 +257,57 @@ can be easily displayed in a chromaticity diagram, for example).
This tag was available in ICC 3.2, but it is removed from This tag was available in ICC 3.2, but it is removed from
version 4. version 4.
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: media_white_point_temperature .. py:attribute:: media_white_point_temperature
:type: Optional[float]
Calculates the white point temperature (see the LCMS documentation Calculates the white point temperature (see the LCMS documentation
for more information). for more information).
:type: :py:class:`float` or ``None``
.. py:attribute:: viewing_condition .. py:attribute:: viewing_condition
:type: Optional[str]
The (English) display string for the viewing conditions (see The (English) display string for the viewing conditions (see
9.2.48 of ICC.1:2010). 9.2.48 of ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: screening_description .. py:attribute:: screening_description
:type: Optional[str]
The (English) display string for the screening conditions. The (English) display string for the screening conditions.
This tag was available in ICC 3.2, but it is removed from This tag was available in ICC 3.2, but it is removed from
version 4. version 4.
:type: :py:class:`unicode` or ``None``
.. py:attribute:: red_primary .. py:attribute:: red_primary
:type: Optional[tuple[tuple[float]]]
The XYZ-transformed of the RGB primary color red (1, 0, 0). The XYZ-transformed of the RGB primary color red (1, 0, 0).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: green_primary .. py:attribute:: green_primary
:type: Optional[tuple[tuple[float]]]
The XYZ-transformed of the RGB primary color green (0, 1, 0). The XYZ-transformed of the RGB primary color green (0, 1, 0).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: blue_primary .. py:attribute:: blue_primary
:type: Optional[tuple[tuple[float]]]
The XYZ-transformed of the RGB primary color blue (0, 0, 1). The XYZ-transformed of the RGB primary color blue (0, 0, 1).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: is_matrix_shaper .. py:attribute:: is_matrix_shaper
:type: bool
True if this profile is implemented as a matrix shaper (see True if this profile is implemented as a matrix shaper (see
documentation on LCMS). documentation on LCMS).
:type: :py:class:`bool`
.. py:attribute:: clut .. py:attribute:: clut
:type: dict[tuple[bool]]
Returns a dictionary of all supported intents and directions for Returns a dictionary of all supported intents and directions for
the CLUT model. the CLUT model.
@ -326,9 +325,8 @@ can be easily displayed in a chromaticity diagram, for example).
The elements of the tuple are booleans. If the value is ``True``, The elements of the tuple are booleans. If the value is ``True``,
that intent is supported for that direction. that intent is supported for that direction.
:type: :py:class:`dict` of boolean 3-tuples
.. py:attribute:: intent_supported .. py:attribute:: intent_supported
:type: dict[tuple[bool]]
Returns a dictionary of all supported intents and directions. Returns a dictionary of all supported intents and directions.
@ -345,64 +343,6 @@ can be easily displayed in a chromaticity diagram, for example).
The elements of the tuple are booleans. If the value is ``True``, The elements of the tuple are booleans. If the value is ``True``,
that intent is supported for that direction. that intent is supported for that direction.
:type: :py:class:`dict` of boolean 3-tuples
.. py:attribute:: color_space
Deprecated but retained for backwards compatibility.
Interpreted value of :py:attr:`.xcolor_space`. May be the
empty string if value could not be decoded.
:type: :py:class:`string`
.. py:attribute:: pcs
Deprecated but retained for backwards compatibility.
Interpreted value of :py:attr:`.connection_space`. May be
the empty string if value could not be decoded.
:type: :py:class:`string`
.. py:attribute:: product_model
Deprecated but retained for backwards compatibility.
ASCII-encoded value of :py:attr:`.model`.
:type: :py:class:`string`
.. py:attribute:: product_manufacturer
Deprecated but retained for backwards compatibility.
ASCII-encoded value of :py:attr:`.manufacturer`.
:type: :py:class:`string`
.. py:attribute:: product_copyright
Deprecated but retained for backwards compatibility.
ASCII-encoded value of :py:attr:`.copyright`.
:type: :py:class:`string`
.. py:attribute:: product_description
Deprecated but retained for backwards compatibility.
ASCII-encoded value of :py:attr:`.profile_description`.
:type: :py:class:`string`
.. py:attribute:: product_desc
Deprecated but retained for backwards compatibility.
ASCII-encoded value of :py:attr:`.profile_description`.
This alias of :py:attr:`.product_description` used to
contain a derived informative string about the profile,
depending on the value of the description, copyright,
manufacturer and model fields).
:type: :py:class:`string`
There is one function defined on the class: There is one function defined on the class:
.. py:method:: is_intent_supported(intent, direction) .. py:method:: is_intent_supported(intent, direction)

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageColor .. py:module:: PIL.ImageColor
.. py:currentmodule:: PIL.ImageColor .. py:currentmodule:: PIL.ImageColor
:py:mod:`ImageColor` Module :py:mod:`~PIL.ImageColor` Module
=========================== ================================
The :py:mod:`ImageColor` module contains color tables and converters from The :py:mod:`~PIL.ImageColor` module contains color tables and converters from
CSS3-style color specifiers to RGB tuples. This module is used by CSS3-style color specifiers to RGB tuples. This module is used by
:py:meth:`PIL.Image.new` and the :py:mod:`~PIL.ImageDraw` module, among :py:meth:`PIL.Image.new` and the :py:mod:`~PIL.ImageDraw` module, among
others. others.

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageDraw .. py:module:: PIL.ImageDraw
.. py:currentmodule:: PIL.ImageDraw .. py:currentmodule:: PIL.ImageDraw
:py:mod:`ImageDraw` Module :py:mod:`~PIL.ImageDraw` Module
========================== ===============================
The :py:mod:`ImageDraw` module provides simple 2D graphics for The :py:mod:`~PIL.ImageDraw` module provides simple 2D graphics for
:py:class:`~PIL.Image.Image` objects. You can use this module to create new :py:class:`~PIL.Image.Image` objects. You can use this module to create new
images, annotate or retouch existing images, and to generate graphics on the images, annotate or retouch existing images, and to generate graphics on the
fly for web use. fly for web use.
@ -125,7 +125,7 @@ Example: Draw Multiline Text
Functions Functions
--------- ---------
.. py:class:: PIL.ImageDraw.Draw(im, mode=None) .. py:method:: Draw(im, mode=None)
Creates an object that can be used to draw in the given image. Creates an object that can be used to draw in the given image.
@ -141,13 +141,13 @@ Functions
Methods Methods
------- -------
.. py:method:: PIL.ImageDraw.ImageDraw.getfont() .. py:method:: ImageDraw.getfont()
Get the current default font. Get the current default font.
:returns: An image font. :returns: An image font.
.. py:method:: PIL.ImageDraw.ImageDraw.arc(xy, start, end, fill=None, width=0) .. py:method:: ImageDraw.arc(xy, start, end, fill=None, width=0)
Draws an arc (a portion of a circle outline) between the start and end Draws an arc (a portion of a circle outline) between the start and end
angles, inside the given bounding box. angles, inside the given bounding box.
@ -163,7 +163,7 @@ Methods
.. versionadded:: 5.3.0 .. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.bitmap(xy, bitmap, fill=None) .. py:method:: ImageDraw.bitmap(xy, bitmap, fill=None)
Draws a bitmap (mask) at the given position, using the current fill color Draws a bitmap (mask) at the given position, using the current fill color
for the non-zero portions. The bitmap should be a valid transparency mask for the non-zero portions. The bitmap should be a valid transparency mask
@ -174,7 +174,7 @@ Methods
To paste pixel data into an image, use the To paste pixel data into an image, use the
:py:meth:`~PIL.Image.Image.paste` method on the image itself. :py:meth:`~PIL.Image.Image.paste` method on the image itself.
.. py:method:: PIL.ImageDraw.ImageDraw.chord(xy, start, end, fill=None, outline=None, width=1) .. py:method:: ImageDraw.chord(xy, start, end, fill=None, outline=None, width=1)
Same as :py:meth:`~PIL.ImageDraw.ImageDraw.arc`, but connects the end points Same as :py:meth:`~PIL.ImageDraw.ImageDraw.arc`, but connects the end points
with a straight line. with a straight line.
@ -188,7 +188,7 @@ Methods
.. versionadded:: 5.3.0 .. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.ellipse(xy, fill=None, outline=None, width=1) .. py:method:: ImageDraw.ellipse(xy, fill=None, outline=None, width=1)
Draws an ellipse inside the given bounding box. Draws an ellipse inside the given bounding box.
@ -201,9 +201,9 @@ Methods
.. versionadded:: 5.3.0 .. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.line(xy, fill=None, width=0, joint=None) .. py:method:: ImageDraw.line(xy, fill=None, width=0, joint=None)
Draws a line between the coordinates in the **xy** list. Draws a line between the coordinates in the ``xy`` list.
:param xy: Sequence of either 2-tuples like ``[(x, y), (x, y), ...]`` or :param xy: Sequence of either 2-tuples like ``[(x, y), (x, y), ...]`` or
numeric values like ``[x, y, x, y, ...]``. numeric values like ``[x, y, x, y, ...]``.
@ -213,11 +213,11 @@ Methods
.. versionadded:: 1.1.5 .. versionadded:: 1.1.5
.. note:: This option was broken until version 1.1.6. .. note:: This option was broken until version 1.1.6.
:param joint: Joint type between a sequence of lines. It can be ``"curve"``, for rounded edges, or ``None``. :param joint: Joint type between a sequence of lines. It can be ``"curve"``, for rounded edges, or :data:`None`.
.. versionadded:: 5.3.0 .. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=1) .. py:method:: ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=1)
Same as arc, but also draws straight lines between the end points and the Same as arc, but also draws straight lines between the end points and the
center of the bounding box. center of the bounding box.
@ -234,7 +234,7 @@ Methods
.. versionadded:: 5.3.0 .. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.point(xy, fill=None) .. py:method:: ImageDraw.point(xy, fill=None)
Draws points (individual pixels) at the given coordinates. Draws points (individual pixels) at the given coordinates.
@ -242,7 +242,7 @@ Methods
numeric values like ``[x, y, x, y, ...]``. numeric values like ``[x, y, x, y, ...]``.
:param fill: Color to use for the point. :param fill: Color to use for the point.
.. py:method:: PIL.ImageDraw.ImageDraw.polygon(xy, fill=None, outline=None) .. py:method:: ImageDraw.polygon(xy, fill=None, outline=None)
Draws a polygon. Draws a polygon.
@ -255,7 +255,7 @@ Methods
:param outline: Color to use for the outline. :param outline: Color to use for the outline.
:param fill: Color to use for the fill. :param fill: Color to use for the fill.
.. py:method:: PIL.ImageDraw.ImageDraw.rectangle(xy, fill=None, outline=None, width=1) .. py:method:: ImageDraw.rectangle(xy, fill=None, outline=None, width=1)
Draws a rectangle. Draws a rectangle.
@ -268,13 +268,13 @@ Methods
.. versionadded:: 5.3.0 .. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.shape(shape, fill=None, outline=None) .. py:method:: ImageDraw.shape(shape, fill=None, outline=None)
.. warning:: This method is experimental. .. warning:: This method is experimental.
Draw a shape. Draw a shape.
.. py:method:: PIL.ImageDraw.ImageDraw.text(xy, text, fill=None, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None, stroke_width=0, stroke_fill=None) .. py:method:: ImageDraw.text(xy, text, fill=None, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None, stroke_width=0, stroke_fill=None)
Draws the string at the given position. Draws the string at the given position.
@ -335,7 +335,7 @@ Methods
.. versionadded:: 6.2.0 .. versionadded:: 6.2.0
.. py:method:: PIL.ImageDraw.ImageDraw.multiline_text(xy, text, fill=None, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None) .. py:method:: ImageDraw.multiline_text(xy, text, fill=None, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None)
Draws the string at the given position. Draws the string at the given position.
@ -382,7 +382,7 @@ Methods
.. versionadded:: 6.0.0 .. versionadded:: 6.0.0
.. py:method:: PIL.ImageDraw.ImageDraw.textsize(text, font=None, spacing=4, direction=None, features=None, language=None, stroke_width=0) .. py:method:: ImageDraw.textsize(text, font=None, spacing=4, direction=None, features=None, language=None, stroke_width=0)
Return the size of the given string, in pixels. Return the size of the given string, in pixels.
@ -430,7 +430,7 @@ Methods
.. versionadded:: 6.2.0 .. versionadded:: 6.2.0
.. py:method:: PIL.ImageDraw.ImageDraw.multiline_textsize(text, font=None, spacing=4, direction=None, features=None, language=None, stroke_width=0) .. py:method:: ImageDraw.multiline_textsize(text, font=None, spacing=4, direction=None, features=None, language=None, stroke_width=0)
Return the size of the given string, in pixels. Return the size of the given string, in pixels.
@ -468,7 +468,7 @@ Methods
.. versionadded:: 6.2.0 .. versionadded:: 6.2.0
.. py:method:: PIL.ImageDraw.getdraw(im=None, hints=None) .. py:method:: getdraw(im=None, hints=None)
.. warning:: This method is experimental. .. warning:: This method is experimental.
@ -479,7 +479,7 @@ Methods
:param hints: An optional list of hints. :param hints: An optional list of hints.
:returns: A (drawing context, drawing resource factory) tuple. :returns: A (drawing context, drawing resource factory) tuple.
.. py:method:: PIL.ImageDraw.floodfill(image, xy, value, border=None, thresh=0) .. py:method:: floodfill(image, xy, value, border=None, thresh=0)
.. warning:: This method is experimental. .. warning:: This method is experimental.

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageEnhance .. py:module:: PIL.ImageEnhance
.. py:currentmodule:: PIL.ImageEnhance .. py:currentmodule:: PIL.ImageEnhance
:py:mod:`ImageEnhance` Module :py:mod:`~PIL.ImageEnhance` Module
============================= ==================================
The :py:mod:`ImageEnhance` module contains a number of classes that can be used The :py:mod:`~PIL.ImageEnhance` module contains a number of classes that can be used
for image enhancement. for image enhancement.
Example: Vary the sharpness of an image Example: Vary the sharpness of an image
@ -29,7 +29,8 @@ Classes
All enhancement classes implement a common interface, containing a single All enhancement classes implement a common interface, containing a single
method: method:
.. py:class:: PIL.ImageEnhance._Enhance .. py:class:: _Enhance
.. py:method:: enhance(factor) .. py:method:: enhance(factor)
Returns an enhanced image. Returns an enhanced image.
@ -40,7 +41,7 @@ method:
etc), and higher values more. There are no restrictions etc), and higher values more. There are no restrictions
on this value. on this value.
.. py:class:: PIL.ImageEnhance.Color(image) .. py:class:: Color(image)
Adjust image color balance. Adjust image color balance.
@ -49,7 +50,7 @@ method:
factor of 0.0 gives a black and white image. A factor of 1.0 gives factor of 0.0 gives a black and white image. A factor of 1.0 gives
the original image. the original image.
.. py:class:: PIL.ImageEnhance.Contrast(image) .. py:class:: Contrast(image)
Adjust image contrast. Adjust image contrast.
@ -57,7 +58,7 @@ method:
to the contrast control on a TV set. An enhancement factor of 0.0 to the contrast control on a TV set. An enhancement factor of 0.0
gives a solid grey image. A factor of 1.0 gives the original image. gives a solid grey image. A factor of 1.0 gives the original image.
.. py:class:: PIL.ImageEnhance.Brightness(image) .. py:class:: Brightness(image)
Adjust image brightness. Adjust image brightness.
@ -65,7 +66,7 @@ method:
enhancement factor of 0.0 gives a black image. A factor of 1.0 gives the enhancement factor of 0.0 gives a black image. A factor of 1.0 gives the
original image. original image.
.. py:class:: PIL.ImageEnhance.Sharpness(image) .. py:class:: Sharpness(image)
Adjust image sharpness. Adjust image sharpness.

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageFile .. py:module:: PIL.ImageFile
.. py:currentmodule:: PIL.ImageFile .. py:currentmodule:: PIL.ImageFile
:py:mod:`ImageFile` Module :py:mod:`~PIL.ImageFile` Module
========================== ===============================
The :py:mod:`ImageFile` module provides support functions for the image open The :py:mod:`~PIL.ImageFile` module provides support functions for the image open
and save functions. and save functions.
In addition, it provides a :py:class:`Parser` class which can be used to decode In addition, it provides a :py:class:`Parser` class which can be used to decode
@ -34,14 +34,21 @@ Example: Parse an image
im.save("copy.jpg") im.save("copy.jpg")
:py:class:`~PIL.ImageFile.Parser` Classes
--------------------------------- -------
.. autoclass:: PIL.ImageFile.Parser() .. autoclass:: PIL.ImageFile.Parser()
:members: :members:
:py:class:`~PIL.ImageFile.PyDecoder`
------------------------------------
.. autoclass:: PIL.ImageFile.PyDecoder() .. autoclass:: PIL.ImageFile.PyDecoder()
:members: :members:
.. autoclass:: PIL.ImageFile.ImageFile()
:member-order: bysource
:members:
:undoc-members:
:show-inheritance:
.. autoclass:: PIL.ImageFile.StubImageFile()
:members:
:show-inheritance:

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageFilter .. py:module:: PIL.ImageFilter
.. py:currentmodule:: PIL.ImageFilter .. py:currentmodule:: PIL.ImageFilter
:py:mod:`ImageFilter` Module :py:mod:`~PIL.ImageFilter` Module
============================ =================================
The :py:mod:`ImageFilter` module contains definitions for a pre-defined set of The :py:mod:`~PIL.ImageFilter` module contains definitions for a pre-defined set of
filters, which can be be used with the :py:meth:`Image.filter() filters, which can be be used with the :py:meth:`Image.filter()
<PIL.Image.Image.filter>` method. <PIL.Image.Image.filter>` method.
@ -66,3 +66,29 @@ image enhancement filters:
.. autoclass:: PIL.ImageFilter.ModeFilter .. autoclass:: PIL.ImageFilter.ModeFilter
:members: :members:
.. class:: Filter
An abstract mixin used for filtering images
(for use with :py:meth:`~PIL.Image.Image.filter`).
Implementors must provide the following method:
.. method:: filter(self, image)
Applies a filter to a single-band image, or a single band of an image.
:returns: A filtered copy of the image.
.. class:: MultibandFilter
An abstract mixin used for filtering multi-band images
(for use with :py:meth:`~PIL.Image.Image.filter`).
Implementors must provide the following method:
.. method:: filter(self, image)
Applies a filter to a multi-band image.
:returns: A filtered copy of the image.

View File

@ -1,12 +1,12 @@
.. py:module:: PIL.ImageFont .. py:module:: PIL.ImageFont
.. py:currentmodule:: PIL.ImageFont .. py:currentmodule:: PIL.ImageFont
:py:mod:`ImageFont` Module :py:mod:`~PIL.ImageFont` Module
========================== ===============================
The :py:mod:`ImageFont` module defines a class with the same name. Instances of The :py:mod:`~PIL.ImageFont` module defines a class with the same name. Instances of
this class store bitmap fonts, and are used with the this class store bitmap fonts, and are used with the
:py:meth:`PIL.ImageDraw.Draw.text` method. :py:meth:`PIL.ImageDraw.ImageDraw.text` method.
PIL uses its own font file format to store bitmap fonts. You can use the PIL uses its own font file format to store bitmap fonts. You can use the
:command:`pilfont` utility from :command:`pilfont` utility from

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageGrab .. py:module:: PIL.ImageGrab
.. py:currentmodule:: PIL.ImageGrab .. py:currentmodule:: PIL.ImageGrab
:py:mod:`ImageGrab` Module :py:mod:`~PIL.ImageGrab` Module
========================== ===============================
The :py:mod:`ImageGrab` module can be used to copy the contents of the screen The :py:mod:`~PIL.ImageGrab` module can be used to copy the contents of the screen
or the clipboard to a PIL image memory. or the clipboard to a PIL image memory.
.. versionadded:: 1.1.3 .. versionadded:: 1.1.3
@ -27,7 +27,7 @@ or the clipboard to a PIL image memory.
.. versionadded:: 6.2.0 .. versionadded:: 6.2.0
:param xdisplay: :param xdisplay:
X11 Display address. Pass ``None`` to grab the default system screen. Pass ``""`` to grab the default X11 screen on Windows or macOS. X11 Display address. Pass :data:`None` to grab the default system screen. Pass ``""`` to grab the default X11 screen on Windows or macOS.
You can check X11 support using :py:func:`PIL.features.check_feature` with ``feature="xcb"``. You can check X11 support using :py:func:`PIL.features.check_feature` with ``feature="xcb"``.

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageMath .. py:module:: PIL.ImageMath
.. py:currentmodule:: PIL.ImageMath .. py:currentmodule:: PIL.ImageMath
:py:mod:`ImageMath` Module :py:mod:`~PIL.ImageMath` Module
========================== ===============================
The :py:mod:`ImageMath` module can be used to evaluate “image expressions”. The The :py:mod:`~PIL.ImageMath` module can be used to evaluate “image expressions”. The
module provides a single :py:meth:`~PIL.ImageMath.eval` function, which takes module provides a single :py:meth:`~PIL.ImageMath.eval` function, which takes
an expression string and one or more images. an expression string and one or more images.
@ -60,9 +60,8 @@ point values, as necessary. For example, if you add two 8-bit images, the
result will be a 32-bit integer image. If you add a floating point constant to result will be a 32-bit integer image. If you add a floating point constant to
an 8-bit image, the result will be a 32-bit floating point image. an 8-bit image, the result will be a 32-bit floating point image.
You can force conversion using the :py:func:`~PIL.ImageMath.convert`, You can force conversion using the ``convert()``, ``float()``, and ``int()``
:py:func:`~PIL.ImageMath.float`, and :py:func:`~PIL.ImageMath.int` functions functions described below.
described below.
Bitwise Operators Bitwise Operators
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
@ -98,20 +97,24 @@ These functions are applied to each individual pixel.
.. py:currentmodule:: None .. py:currentmodule:: None
.. py:function:: abs(image) .. py:function:: abs(image)
:noindex:
Absolute value. Absolute value.
.. py:function:: convert(image, mode) .. py:function:: convert(image, mode)
:noindex:
Convert image to the given mode. The mode must be given as a string Convert image to the given mode. The mode must be given as a string
constant. constant.
.. py:function:: float(image) .. py:function:: float(image)
:noindex:
Convert image to 32-bit floating point. This is equivalent to Convert image to 32-bit floating point. This is equivalent to
convert(image, “F”). convert(image, “F”).
.. py:function:: int(image) .. py:function:: int(image)
:noindex:
Convert image to 32-bit integer. This is equivalent to convert(image, “I”). Convert image to 32-bit integer. This is equivalent to convert(image, “I”).
@ -119,9 +122,11 @@ These functions are applied to each individual pixel.
integers if necessary to get a correct result. integers if necessary to get a correct result.
.. py:function:: max(image1, image2) .. py:function:: max(image1, image2)
:noindex:
Maximum value. Maximum value.
.. py:function:: min(image1, image2) .. py:function:: min(image1, image2)
:noindex:
Minimum value. Minimum value.

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageMorph .. py:module:: PIL.ImageMorph
.. py:currentmodule:: PIL.ImageMorph .. py:currentmodule:: PIL.ImageMorph
:py:mod:`ImageMorph` Module :py:mod:`~PIL.ImageMorph` Module
=========================== ================================
The :py:mod:`ImageMorph` module provides morphology operations on images. The :py:mod:`~PIL.ImageMorph` module provides morphology operations on images.
.. automodule:: PIL.ImageMorph .. automodule:: PIL.ImageMorph
:members: :members:

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageOps .. py:module:: PIL.ImageOps
.. py:currentmodule:: PIL.ImageOps .. py:currentmodule:: PIL.ImageOps
:py:mod:`ImageOps` Module :py:mod:`~PIL.ImageOps` Module
========================== ==============================
The :py:mod:`ImageOps` module contains a number of ready-made image The :py:mod:`~PIL.ImageOps` module contains a number of ready-made image
processing operations. This module is somewhat experimental, and most operators processing operations. This module is somewhat experimental, and most operators
only work on L and RGB images. only work on L and RGB images.

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImagePalette .. py:module:: PIL.ImagePalette
.. py:currentmodule:: PIL.ImagePalette .. py:currentmodule:: PIL.ImagePalette
:py:mod:`ImagePalette` Module :py:mod:`~PIL.ImagePalette` Module
============================= ==================================
The :py:mod:`ImagePalette` module contains a class of the same name to The :py:mod:`~PIL.ImagePalette` module contains a class of the same name to
represent the color palette of palette mapped images. represent the color palette of palette mapped images.
.. note:: .. note::

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImagePath .. py:module:: PIL.ImagePath
.. py:currentmodule:: PIL.ImagePath .. py:currentmodule:: PIL.ImagePath
:py:mod:`ImagePath` Module :py:mod:`~PIL.ImagePath` Module
========================== ===============================
The :py:mod:`ImagePath` module is used to store and manipulate 2-dimensional The :py:mod:`~PIL.ImagePath` module is used to store and manipulate 2-dimensional
vector data. Path objects can be passed to the methods on the vector data. Path objects can be passed to the methods on the
:py:mod:`~PIL.ImageDraw` module. :py:mod:`~PIL.ImageDraw` module.

View File

@ -1,15 +1,15 @@
.. py:module:: PIL.ImageQt .. py:module:: PIL.ImageQt
.. py:currentmodule:: PIL.ImageQt .. py:currentmodule:: PIL.ImageQt
:py:mod:`ImageQt` Module :py:mod:`~PIL.ImageQt` Module
======================== =============================
The :py:mod:`ImageQt` module contains support for creating PyQt5 or PySide2 QImage The :py:mod:`~PIL.ImageQt` module contains support for creating PyQt5 or PySide2 QImage
objects from PIL images. objects from PIL images.
.. versionadded:: 1.1.6 .. versionadded:: 1.1.6
.. py:class:: ImageQt.ImageQt(image) .. py:class:: ImageQt(image)
Creates an :py:class:`~PIL.ImageQt.ImageQt` object from a PIL Creates an :py:class:`~PIL.ImageQt.ImageQt` object from a PIL
:py:class:`~PIL.Image.Image` object. This class is a subclass of :py:class:`~PIL.Image.Image` object. This class is a subclass of

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageSequence .. py:module:: PIL.ImageSequence
.. py:currentmodule:: PIL.ImageSequence .. py:currentmodule:: PIL.ImageSequence
:py:mod:`ImageSequence` Module :py:mod:`~PIL.ImageSequence` Module
============================== ===================================
The :py:mod:`ImageSequence` module contains a wrapper class that lets you The :py:mod:`~PIL.ImageSequence` module contains a wrapper class that lets you
iterate over the frames of an image sequence. iterate over the frames of an image sequence.
Extracting frames from an animation Extracting frames from an animation

View File

@ -0,0 +1,27 @@
.. py:module:: PIL.ImageShow
.. py:currentmodule:: PIL.ImageShow
:py:mod:`~PIL.ImageShow` Module
===============================
The :py:mod:`~PIL.ImageShow` Module is used to display images.
All default viewers convert the image to be shown to PNG format.
.. autofunction:: PIL.ImageShow.show
.. autoclass:: WindowsViewer
.. autoclass:: MacViewer
.. class:: UnixViewer
The following viewers may be registered on Unix-based systems, if the given command is found:
.. autoclass:: PIL.ImageShow.DisplayViewer
.. autoclass:: PIL.ImageShow.EogViewer
.. autoclass:: PIL.ImageShow.XVViewer
.. autofunction:: PIL.ImageShow.register
.. autoclass:: PIL.ImageShow.Viewer
:member-order: bysource
:members:
:undoc-members:

View File

@ -1,13 +1,13 @@
.. py:module:: PIL.ImageStat .. py:module:: PIL.ImageStat
.. py:currentmodule:: PIL.ImageStat .. py:currentmodule:: PIL.ImageStat
:py:mod:`ImageStat` Module :py:mod:`~PIL.ImageStat` Module
========================== ===============================
The :py:mod:`ImageStat` module calculates global statistics for an image, or The :py:mod:`~PIL.ImageStat` module calculates global statistics for an image, or
for a region of an image. for a region of an image.
.. py:class:: PIL.ImageStat.Stat(image_or_list, mask=None) .. py:class:: Stat(image_or_list, mask=None)
Calculate statistics for the given image. If a mask is included, Calculate statistics for the given image. If a mask is included,
only the regions covered by that mask are included in the only the regions covered by that mask are included in the
@ -22,13 +22,13 @@ for a region of an image.
.. note:: .. note::
This relies on the :py:meth:`~PIL.Image.histogram` method, and This relies on the :py:meth:`~PIL.Image.Image.histogram` method, and
simply returns the low and high bins used. This is correct for simply returns the low and high bins used. This is correct for
images with 8 bits per channel, but fails for other modes such as images with 8 bits per channel, but fails for other modes such as
``I`` or ``F``. Instead, use :py:meth:`~PIL.Image.getextrema` to ``I`` or ``F``. Instead, use :py:meth:`~PIL.Image.Image.getextrema` to
return per-band extrema for the image. This is more correct and return per-band extrema for the image. This is more correct and
efficient because, for non-8-bit modes, the histogram method uses efficient because, for non-8-bit modes, the histogram method uses
:py:meth:`~PIL.Image.getextrema` to determine the bins used. :py:meth:`~PIL.Image.Image.getextrema` to determine the bins used.
.. py:attribute:: count .. py:attribute:: count

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageTk .. py:module:: PIL.ImageTk
.. py:currentmodule:: PIL.ImageTk .. py:currentmodule:: PIL.ImageTk
:py:mod:`ImageTk` Module :py:mod:`~PIL.ImageTk` Module
======================== =============================
The :py:mod:`ImageTk` module contains support to create and modify Tkinter The :py:mod:`~PIL.ImageTk` module contains support to create and modify Tkinter
BitmapImage and PhotoImage objects from PIL images. BitmapImage and PhotoImage objects from PIL images.
For examples, see the demo programs in the Scripts directory. For examples, see the demo programs in the Scripts directory.

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.ImageWin .. py:module:: PIL.ImageWin
.. py:currentmodule:: PIL.ImageWin .. py:currentmodule:: PIL.ImageWin
:py:mod:`ImageWin` Module (Windows-only) :py:mod:`~PIL.ImageWin` Module (Windows-only)
======================================== =============================================
The :py:mod:`ImageWin` module contains support to create and display images on The :py:mod:`~PIL.ImageWin` module contains support to create and display images on
Windows. Windows.
ImageWin can be used with PythonWin and other user interface toolkits that ImageWin can be used with PythonWin and other user interface toolkits that

View File

@ -0,0 +1,11 @@
.. py:currentmodule:: PIL.JpegPresets
:py:mod:`~PIL.JpegPresets` Module
=================================
.. automodule:: PIL.JpegPresets
.. data:: presets
:type: dict
A dictionary of all supported presets.

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.PSDraw .. py:module:: PIL.PSDraw
.. py:currentmodule:: PIL.PSDraw .. py:currentmodule:: PIL.PSDraw
:py:mod:`PSDraw` Module :py:mod:`~PIL.PSDraw` Module
======================= ============================
The :py:mod:`PSDraw` module provides simple print support for Postscript The :py:mod:`~PIL.PSDraw` module provides simple print support for PostScript
printers. You can print text, graphics and images through this module. printers. You can print text, graphics and images through this module.
.. autoclass:: PIL.PSDraw.PSDraw .. autoclass:: PIL.PSDraw.PSDraw

View File

@ -1,10 +1,10 @@
.. py:module:: PIL.PyAccess .. py:module:: PIL.PyAccess
.. py:currentmodule:: PIL.PyAccess .. py:currentmodule:: PIL.PyAccess
:py:mod:`PyAccess` Module :py:mod:`~PIL.PyAccess` Module
========================= ==============================
The :py:mod:`PyAccess` module provides a CFFI/Python implementation of the :ref:`PixelAccess`. This implementation is far faster on PyPy than the PixelAccess version. The :py:mod:`~PIL.PyAccess` module provides a CFFI/Python implementation of the :ref:`PixelAccess`. This implementation is far faster on PyPy than the PixelAccess version.
.. note:: Accessing individual pixels is fairly slow. If you are .. note:: Accessing individual pixels is fairly slow. If you are
looping over all of the pixels in an image, there is likely looping over all of the pixels in an image, there is likely

View File

@ -1,17 +1,17 @@
.. py:module:: PIL.TiffTags .. py:module:: PIL.TiffTags
.. py:currentmodule:: PIL.TiffTags .. py:currentmodule:: PIL.TiffTags
:py:mod:`TiffTags` Module :py:mod:`~PIL.TiffTags` Module
========================= ==============================
The :py:mod:`TiffTags` module exposes many of the standard TIFF The :py:mod:`~PIL.TiffTags` module exposes many of the standard TIFF
metadata tag numbers, names, and type information. metadata tag numbers, names, and type information.
.. method:: lookup(tag) .. method:: lookup(tag)
:param tag: Integer tag number :param tag: Integer tag number
:returns: Taginfo namedtuple, From the ``TAGS_V2`` info if possible, :returns: Taginfo namedtuple, From the :py:data:`~PIL.TiffTags.TAGS_V2` info if possible,
otherwise just populating the value and name from ``TAGS``. otherwise just populating the value and name from :py:data:`~PIL.TiffTags.TAGS`.
If the tag is not recognized, "unknown" is returned for the name If the tag is not recognized, "unknown" is returned for the name
.. versionadded:: 3.1.0 .. versionadded:: 3.1.0
@ -22,7 +22,7 @@ metadata tag numbers, names, and type information.
:param value: Integer Tag Number :param value: Integer Tag Number
:param name: Tag Name :param name: Tag Name
:param type: Integer type from :py:attr:`PIL.TiffTags.TYPES` :param type: Integer type from :py:data:`PIL.TiffTags.TYPES`
:param length: Array length: 0 == variable, 1 == single value, n = fixed :param length: Array length: 0 == variable, 1 == single value, n = fixed
:param enum: Dict of name:integer value options for an enumeration :param enum: Dict of name:integer value options for an enumeration
@ -33,15 +33,17 @@ metadata tag numbers, names, and type information.
.. versionadded:: 3.0.0 .. versionadded:: 3.0.0
.. py:attribute:: PIL.TiffTags.TAGS_V2 .. py:data:: PIL.TiffTags.TAGS_V2
:type: dict
The ``TAGS_V2`` dictionary maps 16-bit integer tag numbers to The ``TAGS_V2`` dictionary maps 16-bit integer tag numbers to
:py:class:`PIL.TagTypes.TagInfo` tuples for metadata fields defined in the TIFF :py:class:`PIL.TiffTags.TagInfo` tuples for metadata fields defined in the TIFF
spec. spec.
.. versionadded:: 3.0.0 .. versionadded:: 3.0.0
.. py:attribute:: PIL.TiffTags.TAGS .. py:data:: PIL.TiffTags.TAGS
:type: dict
The ``TAGS`` dictionary maps 16-bit integer TIFF tag number to The ``TAGS`` dictionary maps 16-bit integer TIFF tag number to
descriptive string names. For instance: descriptive string names. For instance:
@ -50,10 +52,16 @@ metadata tag numbers, names, and type information.
>>> TAGS[0x010e] >>> TAGS[0x010e]
'ImageDescription' 'ImageDescription'
This dictionary contains a superset of the tags in TAGS_V2, common This dictionary contains a superset of the tags in :py:data:`~PIL.TiffTags.TAGS_V2`, common
EXIF tags, and other well known metadata tags. EXIF tags, and other well known metadata tags.
.. py:attribute:: PIL.TiffTags.TYPES .. py:data:: PIL.TiffTags.TYPES
:type: dict
The ``TYPES`` dictionary maps the TIFF type short integer to a The ``TYPES`` dictionary maps the TIFF type short integer to a
human readable type name. human readable type name.
.. py:data:: PIL.TiffTags.LIBTIFF_CORE
:type: list
A list of supported tag IDs when writing using LibTIFF.

View File

@ -1,8 +1,8 @@
.. py:module:: PIL.features .. py:module:: PIL.features
.. py:currentmodule:: PIL.features .. py:currentmodule:: PIL.features
:py:mod:`features` Module :py:mod:`~PIL.features` Module
========================== ==============================
The :py:mod:`PIL.features` module can be used to detect which Pillow features are available on your system. The :py:mod:`PIL.features` module can be used to detect which Pillow features are available on your system.

View File

@ -7,8 +7,8 @@ Reference
Image Image
ImageChops ImageChops
ImageColor
ImageCms ImageCms
ImageColor
ImageDraw ImageDraw
ImageEnhance ImageEnhance
ImageFile ImageFile
@ -22,11 +22,13 @@ Reference
ImagePath ImagePath
ImageQt ImageQt
ImageSequence ImageSequence
ImageShow
ImageStat ImageStat
ImageTk ImageTk
ImageWin ImageWin
ExifTags ExifTags
TiffTags TiffTags
JpegPresets
PSDraw PSDraw
PixelAccess PixelAccess
PyAccess PyAccess

View File

@ -7,4 +7,4 @@ Internal Reference Docs
open_files open_files
limits limits
block_allocator block_allocator
internal_modules

View File

@ -0,0 +1,47 @@
Internal Modules
================
:mod:`~PIL._binary` Module
--------------------------
.. automodule:: PIL._binary
:members:
:undoc-members:
:show-inheritance:
:mod:`~PIL._tkinter_finder` Module
----------------------------------
.. automodule:: PIL._tkinter_finder
:members:
:undoc-members:
:show-inheritance:
:mod:`~PIL._util` Module
------------------------
.. automodule:: PIL._util
:members:
:undoc-members:
:show-inheritance:
:mod:`~PIL._version` Module
---------------------------
.. module:: PIL._version
.. data:: __version__
:annotation:
:type: str
This is the master version number for Pillow,
all other uses reference this module.
:mod:`PIL.Image.core` Module
----------------------------
.. module:: PIL._imaging
.. module:: PIL.Image.core
An internal interface module previously known as :mod:`~PIL._imaging`,
implemented in :file:`_imaging.c`.

View File

@ -1,340 +1,332 @@
Plugin reference Plugin reference
================ ================
:mod:`BmpImagePlugin` Module :mod:`~PIL.BmpImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.BmpImagePlugin .. automodule:: PIL.BmpImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`BufrStubImagePlugin` Module :mod:`~PIL.BufrStubImagePlugin` Module
--------------------------------- --------------------------------------
.. automodule:: PIL.BufrStubImagePlugin .. automodule:: PIL.BufrStubImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`CurImagePlugin` Module :mod:`~PIL.CurImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.CurImagePlugin .. automodule:: PIL.CurImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`DcxImagePlugin` Module :mod:`~PIL.DcxImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.DcxImagePlugin .. automodule:: PIL.DcxImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`EpsImagePlugin` Module :mod:`~PIL.EpsImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.EpsImagePlugin .. automodule:: PIL.EpsImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`FitsStubImagePlugin` Module :mod:`~PIL.FitsStubImagePlugin` Module
--------------------------------- --------------------------------------
.. automodule:: PIL.FitsStubImagePlugin .. automodule:: PIL.FitsStubImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`FliImagePlugin` Module :mod:`~PIL.FliImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.FliImagePlugin .. automodule:: PIL.FliImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`FpxImagePlugin` Module :mod:`~PIL.FpxImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.FpxImagePlugin .. automodule:: PIL.FpxImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`GbrImagePlugin` Module :mod:`~PIL.GbrImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.GbrImagePlugin .. automodule:: PIL.GbrImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`GifImagePlugin` Module :mod:`~PIL.GifImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.GifImagePlugin .. automodule:: PIL.GifImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`GribStubImagePlugin` Module :mod:`~PIL.GribStubImagePlugin` Module
--------------------------------- --------------------------------------
.. automodule:: PIL.GribStubImagePlugin .. automodule:: PIL.GribStubImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`Hdf5StubImagePlugin` Module :mod:`~PIL.Hdf5StubImagePlugin` Module
--------------------------------- --------------------------------------
.. automodule:: PIL.Hdf5StubImagePlugin .. automodule:: PIL.Hdf5StubImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`IcnsImagePlugin` Module :mod:`~PIL.IcnsImagePlugin` Module
----------------------------- ----------------------------------
.. automodule:: PIL.IcnsImagePlugin .. automodule:: PIL.IcnsImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`IcoImagePlugin` Module :mod:`~PIL.IcoImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.IcoImagePlugin .. automodule:: PIL.IcoImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`ImImagePlugin` Module :mod:`~PIL.ImImagePlugin` Module
--------------------------- --------------------------------
.. automodule:: PIL.ImImagePlugin .. automodule:: PIL.ImImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`ImtImagePlugin` Module :mod:`~PIL.ImtImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.ImtImagePlugin .. automodule:: PIL.ImtImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`IptcImagePlugin` Module :mod:`~PIL.IptcImagePlugin` Module
----------------------------- ----------------------------------
.. automodule:: PIL.IptcImagePlugin .. automodule:: PIL.IptcImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`JpegImagePlugin` Module :mod:`~PIL.JpegImagePlugin` Module
----------------------------- ----------------------------------
.. automodule:: PIL.JpegImagePlugin .. automodule:: PIL.JpegImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`Jpeg2KImagePlugin` Module :mod:`~PIL.Jpeg2KImagePlugin` Module
------------------------------- ------------------------------------
.. automodule:: PIL.Jpeg2KImagePlugin .. automodule:: PIL.Jpeg2KImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`McIdasImagePlugin` Module :mod:`~PIL.McIdasImagePlugin` Module
------------------------------- ------------------------------------
.. automodule:: PIL.McIdasImagePlugin .. automodule:: PIL.McIdasImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`MicImagePlugin` Module :mod:`~PIL.MicImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.MicImagePlugin .. automodule:: PIL.MicImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`MpegImagePlugin` Module :mod:`~PIL.MpegImagePlugin` Module
----------------------------- ----------------------------------
.. automodule:: PIL.MpegImagePlugin .. automodule:: PIL.MpegImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`MspImagePlugin` Module :mod:`~PIL.MspImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.MspImagePlugin .. automodule:: PIL.MspImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`PalmImagePlugin` Module :mod:`~PIL.PalmImagePlugin` Module
----------------------------- ----------------------------------
.. automodule:: PIL.PalmImagePlugin .. automodule:: PIL.PalmImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`PcdImagePlugin` Module :mod:`~PIL.PcdImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.PcdImagePlugin .. automodule:: PIL.PcdImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`PcxImagePlugin` Module :mod:`~PIL.PcxImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.PcxImagePlugin .. automodule:: PIL.PcxImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`PdfImagePlugin` Module :mod:`~PIL.PdfImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.PdfImagePlugin .. automodule:: PIL.PdfImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`PixarImagePlugin` Module :mod:`~PIL.PixarImagePlugin` Module
------------------------------ -----------------------------------
.. automodule:: PIL.PixarImagePlugin .. automodule:: PIL.PixarImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`PngImagePlugin` Module :mod:`~PIL.PngImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.PngImagePlugin .. automodule:: PIL.PngImagePlugin
:members: ChunkStream, PngStream, getchunks, is_cid, putchunk :members: ChunkStream, PngImageFile, PngStream, getchunks, is_cid, putchunk,
:show-inheritance: MAX_TEXT_CHUNK, MAX_TEXT_MEMORY, APNG_BLEND_OP_SOURCE, APNG_BLEND_OP_OVER,
.. autoclass:: PIL.PngImagePlugin.ChunkStream APNG_DISPOSE_OP_NONE, APNG_DISPOSE_OP_BACKGROUND, APNG_DISPOSE_OP_PREVIOUS
:members:
:undoc-members:
:show-inheritance:
.. autoclass:: PIL.PngImagePlugin.PngImageFile
:members:
:undoc-members:
:show-inheritance:
.. autoclass:: PIL.PngImagePlugin.PngStream
:members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:member-order: groupwise
:mod:`PpmImagePlugin` Module :mod:`~PIL.PpmImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.PpmImagePlugin .. automodule:: PIL.PpmImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`PsdImagePlugin` Module :mod:`~PIL.PsdImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.PsdImagePlugin .. automodule:: PIL.PsdImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`SgiImagePlugin` Module :mod:`~PIL.SgiImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.SgiImagePlugin .. automodule:: PIL.SgiImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`SpiderImagePlugin` Module :mod:`~PIL.SpiderImagePlugin` Module
------------------------------- ------------------------------------
.. automodule:: PIL.SpiderImagePlugin .. automodule:: PIL.SpiderImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`SunImagePlugin` Module :mod:`~PIL.SunImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.SunImagePlugin .. automodule:: PIL.SunImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`TgaImagePlugin` Module :mod:`~PIL.TgaImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.TgaImagePlugin .. automodule:: PIL.TgaImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`TiffImagePlugin` Module :mod:`~PIL.TiffImagePlugin` Module
----------------------------- ----------------------------------
.. automodule:: PIL.TiffImagePlugin .. automodule:: PIL.TiffImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`WebPImagePlugin` Module :mod:`~PIL.WebPImagePlugin` Module
----------------------------- ----------------------------------
.. automodule:: PIL.WebPImagePlugin .. automodule:: PIL.WebPImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`WmfImagePlugin` Module :mod:`~PIL.WmfImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.WmfImagePlugin .. automodule:: PIL.WmfImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`XVThumbImagePlugin` Module :mod:`~PIL.XVThumbImagePlugin` Module
-------------------------------- -------------------------------------
.. automodule:: PIL.XVThumbImagePlugin .. automodule:: PIL.XVThumbImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`XbmImagePlugin` Module :mod:`~PIL.XbmImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.XbmImagePlugin .. automodule:: PIL.XbmImagePlugin
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
:mod:`XpmImagePlugin` Module :mod:`~PIL.XpmImagePlugin` Module
---------------------------- ---------------------------------
.. automodule:: PIL.XpmImagePlugin .. automodule:: PIL.XpmImagePlugin
:members: :members:

View File

@ -29,53 +29,53 @@ Image resizing filters
Image resizing methods :py:meth:`~PIL.Image.Image.resize` and Image resizing methods :py:meth:`~PIL.Image.Image.resize` and
:py:meth:`~PIL.Image.Image.thumbnail` take a ``resample`` argument, which tells :py:meth:`~PIL.Image.Image.thumbnail` take a ``resample`` argument, which tells
which filter should be used for resampling. Possible values are: which filter should be used for resampling. Possible values are:
:py:attr:`PIL.Image.NEAREST`, :py:attr:`PIL.Image.BILINEAR`, :py:data:`PIL.Image.NEAREST`, :py:data:`PIL.Image.BILINEAR`,
:py:attr:`PIL.Image.BICUBIC` and :py:attr:`PIL.Image.ANTIALIAS`. :py:data:`PIL.Image.BICUBIC` and :py:data:`PIL.Image.ANTIALIAS`.
Almost all of them were changed in this version. Almost all of them were changed in this version.
Bicubic and bilinear downscaling Bicubic and bilinear downscaling
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
From the beginning :py:attr:`~PIL.Image.BILINEAR` and From the beginning :py:data:`~PIL.Image.BILINEAR` and
:py:attr:`~PIL.Image.BICUBIC` filters were based on affine transformations :py:data:`~PIL.Image.BICUBIC` filters were based on affine transformations
and used a fixed number of pixels from the source image for every destination and used a fixed number of pixels from the source image for every destination
pixel (2x2 pixels for :py:attr:`~PIL.Image.BILINEAR` and 4x4 for pixel (2x2 pixels for :py:data:`~PIL.Image.BILINEAR` and 4x4 for
:py:attr:`~PIL.Image.BICUBIC`). This gave an unsatisfactory result for :py:data:`~PIL.Image.BICUBIC`). This gave an unsatisfactory result for
downscaling. At the same time, a high quality convolutions-based algorithm with downscaling. At the same time, a high quality convolutions-based algorithm with
flexible kernel was used for :py:attr:`~PIL.Image.ANTIALIAS` filter. flexible kernel was used for :py:data:`~PIL.Image.ANTIALIAS` filter.
Starting from Pillow 2.7.0, a high quality convolutions-based algorithm is used Starting from Pillow 2.7.0, a high quality convolutions-based algorithm is used
for all of these three filters. for all of these three filters.
If you have previously used any tricks to maintain quality when downscaling with If you have previously used any tricks to maintain quality when downscaling with
:py:attr:`~PIL.Image.BILINEAR` and :py:attr:`~PIL.Image.BICUBIC` filters :py:data:`~PIL.Image.BILINEAR` and :py:data:`~PIL.Image.BICUBIC` filters
(for example, reducing within several steps), they are unnecessary now. (for example, reducing within several steps), they are unnecessary now.
Antialias renamed to Lanczos Antialias renamed to Lanczos
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A new :py:attr:`PIL.Image.LANCZOS` constant was added instead of A new :py:data:`PIL.Image.LANCZOS` constant was added instead of
:py:attr:`~PIL.Image.ANTIALIAS`. :py:data:`~PIL.Image.ANTIALIAS`.
When :py:attr:`~PIL.Image.ANTIALIAS` was initially added, it was the only When :py:data:`~PIL.Image.ANTIALIAS` was initially added, it was the only
high-quality filter based on convolutions. It's name was supposed to reflect high-quality filter based on convolutions. It's name was supposed to reflect
this. Starting from Pillow 2.7.0 all resize method are based on convolutions. this. Starting from Pillow 2.7.0 all resize method are based on convolutions.
All of them are antialias from now on. And the real name of the All of them are antialias from now on. And the real name of the
:py:attr:`~PIL.Image.ANTIALIAS` filter is Lanczos filter. :py:data:`~PIL.Image.ANTIALIAS` filter is Lanczos filter.
The :py:attr:`~PIL.Image.ANTIALIAS` constant is left for backward compatibility The :py:data:`~PIL.Image.ANTIALIAS` constant is left for backward compatibility
and is an alias for :py:attr:`~PIL.Image.LANCZOS`. and is an alias for :py:data:`~PIL.Image.LANCZOS`.
Lanczos upscaling quality Lanczos upscaling quality
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
The image upscaling quality with :py:attr:`~PIL.Image.LANCZOS` filter was The image upscaling quality with :py:data:`~PIL.Image.LANCZOS` filter was
almost the same as :py:attr:`~PIL.Image.BILINEAR` due to bug. This has been fixed. almost the same as :py:data:`~PIL.Image.BILINEAR` due to bug. This has been fixed.
Bicubic upscaling quality Bicubic upscaling quality
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
The :py:attr:`~PIL.Image.BICUBIC` filter for affine transformations produced The :py:data:`~PIL.Image.BICUBIC` filter for affine transformations produced
sharp, slightly pixelated image for upscaling. Bicubic for convolutions is sharp, slightly pixelated image for upscaling. Bicubic for convolutions is
more soft. more soft.
@ -84,42 +84,42 @@ Resize performance
In most cases, convolution is more a expensive algorithm for downscaling In most cases, convolution is more a expensive algorithm for downscaling
because it takes into account all the pixels of source image. Therefore because it takes into account all the pixels of source image. Therefore
:py:attr:`~PIL.Image.BILINEAR` and :py:attr:`~PIL.Image.BICUBIC` filters' :py:data:`~PIL.Image.BILINEAR` and :py:data:`~PIL.Image.BICUBIC` filters'
performance can be lower than before. On the other hand the quality of performance can be lower than before. On the other hand the quality of
:py:attr:`~PIL.Image.BILINEAR` and :py:attr:`~PIL.Image.BICUBIC` was close to :py:data:`~PIL.Image.BILINEAR` and :py:data:`~PIL.Image.BICUBIC` was close to
:py:attr:`~PIL.Image.NEAREST`. So if such quality is suitable for your tasks :py:data:`~PIL.Image.NEAREST`. So if such quality is suitable for your tasks
you can switch to :py:attr:`~PIL.Image.NEAREST` filter for downscaling, you can switch to :py:data:`~PIL.Image.NEAREST` filter for downscaling,
which will give a huge improvement in performance. which will give a huge improvement in performance.
At the same time performance of convolution resampling for downscaling has been At the same time performance of convolution resampling for downscaling has been
improved by around a factor of two compared to the previous version. improved by around a factor of two compared to the previous version.
The upscaling performance of the :py:attr:`~PIL.Image.LANCZOS` filter has The upscaling performance of the :py:data:`~PIL.Image.LANCZOS` filter has
remained the same. For :py:attr:`~PIL.Image.BILINEAR` filter it has improved by remained the same. For :py:data:`~PIL.Image.BILINEAR` filter it has improved by
1.5 times and for :py:attr:`~PIL.Image.BICUBIC` by four times. 1.5 times and for :py:data:`~PIL.Image.BICUBIC` by four times.
Default filter for thumbnails Default filter for thumbnails
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In Pillow 2.5 the default filter for :py:meth:`~PIL.Image.Image.thumbnail` was In Pillow 2.5 the default filter for :py:meth:`~PIL.Image.Image.thumbnail` was
changed from :py:attr:`~PIL.Image.NEAREST` to :py:attr:`~PIL.Image.ANTIALIAS`. changed from :py:data:`~PIL.Image.NEAREST` to :py:data:`~PIL.Image.ANTIALIAS`.
Antialias was chosen because all the other filters gave poor quality for Antialias was chosen because all the other filters gave poor quality for
reduction. Starting from Pillow 2.7.0, :py:attr:`~PIL.Image.ANTIALIAS` has been reduction. Starting from Pillow 2.7.0, :py:data:`~PIL.Image.ANTIALIAS` has been
replaced with :py:attr:`~PIL.Image.BICUBIC`, because it's faster and replaced with :py:data:`~PIL.Image.BICUBIC`, because it's faster and
:py:attr:`~PIL.Image.ANTIALIAS` doesn't give any advantages after :py:data:`~PIL.Image.ANTIALIAS` doesn't give any advantages after
downscaling with libjpeg, which uses supersampling internally, not convolutions. downscaling with libjpeg, which uses supersampling internally, not convolutions.
Image transposition Image transposition
------------------- -------------------
A new method :py:attr:`PIL.Image.TRANSPOSE` has been added for the A new method :py:data:`PIL.Image.TRANSPOSE` has been added for the
:py:meth:`~PIL.Image.Image.transpose` operation in addition to :py:meth:`~PIL.Image.Image.transpose` operation in addition to
:py:attr:`~PIL.Image.FLIP_LEFT_RIGHT`, :py:attr:`~PIL.Image.FLIP_TOP_BOTTOM`, :py:data:`~PIL.Image.FLIP_LEFT_RIGHT`, :py:data:`~PIL.Image.FLIP_TOP_BOTTOM`,
:py:attr:`~PIL.Image.ROTATE_90`, :py:attr:`~PIL.Image.ROTATE_180`, :py:data:`~PIL.Image.ROTATE_90`, :py:data:`~PIL.Image.ROTATE_180`,
:py:attr:`~PIL.Image.ROTATE_270`. :py:attr:`~PIL.Image.TRANSPOSE` is an algebra :py:data:`~PIL.Image.ROTATE_270`. :py:data:`~PIL.Image.TRANSPOSE` is an algebra
transpose, with an image reflected across its main diagonal. transpose, with an image reflected across its main diagonal.
The speed of :py:attr:`~PIL.Image.ROTATE_90`, :py:attr:`~PIL.Image.ROTATE_270` The speed of :py:data:`~PIL.Image.ROTATE_90`, :py:data:`~PIL.Image.ROTATE_270`
and :py:attr:`~PIL.Image.TRANSPOSE` has been significantly improved for large and :py:data:`~PIL.Image.TRANSPOSE` has been significantly improved for large
images which don't fit in the processor cache. images which don't fit in the processor cache.
Gaussian blur and unsharp mask Gaussian blur and unsharp mask

View File

@ -10,9 +10,9 @@ Several deprecated items have been removed.
resolution', 'resolution unit', and 'date time' has been resolution', 'resolution unit', and 'date time' has been
removed. Underscores should be used instead. removed. Underscores should be used instead.
* The methods :py:meth:`PIL.ImageDraw.ImageDraw.setink`, * The methods ``PIL.ImageDraw.ImageDraw.setink``,
:py:meth:`PIL.ImageDraw.ImageDraw.setfill`, and ``PIL.ImageDraw.ImageDraw.setfill``, and
:py:meth:`PIL.ImageDraw.ImageDraw.setfont` have been removed. ``PIL.ImageDraw.ImageDraw.setfont`` have been removed.
Closing Files When Opening Images Closing Files When Opening Images

View File

@ -27,16 +27,16 @@ New DecompressionBomb Warning
:py:meth:`PIL.Image.Image.crop` now may raise a DecompressionBomb :py:meth:`PIL.Image.Image.crop` now may raise a DecompressionBomb
warning if the crop region enlarges the image over the threshold warning if the crop region enlarges the image over the threshold
specified by :py:attr:`PIL.Image.MAX_PIXELS`. specified by :py:data:`PIL.Image.MAX_IMAGE_PIXELS`.
Removed Deprecated Items Removed Deprecated Items
======================== ========================
Several deprecated items have been removed. Several deprecated items have been removed.
* The methods :py:meth:`PIL.ImageWin.Dib.fromstring`, * The methods ``PIL.ImageWin.Dib.fromstring``,
:py:meth:`PIL.ImageWin.Dib.tostring` and ``PIL.ImageWin.Dib.tostring`` and
:py:meth:`PIL.TiffImagePlugin.ImageFileDirectory_v2.as_dict` have ``PIL.TiffImagePlugin.ImageFileDirectory_v2.as_dict`` have
been removed. been removed.
* Before Pillow 4.2.0, attempting to save an RGBA image as JPEG would * Before Pillow 4.2.0, attempting to save an RGBA image as JPEG would

View File

@ -124,7 +124,7 @@ This release contains several performance improvements:
* ``Image.transpose`` has been accelerated 15% or more by using a cache * ``Image.transpose`` has been accelerated 15% or more by using a cache
friendly algorithm. friendly algorithm.
* ImageFilters based on Kernel convolution are significantly faster * ImageFilters based on Kernel convolution are significantly faster
due to the new MultibandFilter feature. due to the new :py:class:`~PIL.ImageFilter.MultibandFilter` feature.
* All memory allocation for images is now done in blocks, rather than * All memory allocation for images is now done in blocks, rather than
falling back to an allocation for each scan line for images larger falling back to an allocation for each scan line for images larger
than the block size. than the block size.

View File

@ -34,7 +34,7 @@ Curved joints for line sequences
``ImageDraw.Draw.line`` draws a line, or lines, between points. Previously, ``ImageDraw.Draw.line`` draws a line, or lines, between points. Previously,
when multiple points are given, for a larger ``width``, the joints between when multiple points are given, for a larger ``width``, the joints between
these lines looked unsightly. There is now an additional optional argument, these lines looked unsightly. There is now an additional optional argument,
``joint``, defaulting to ``None``. When it is set to ``curved``, the joints ``joint``, defaulting to :data:`None`. When it is set to ``curved``, the joints
between the lines will become rounded. between the lines will become rounded.
ImageOps.colorize ImageOps.colorize

View File

@ -66,7 +66,7 @@ See :ref:`concept-filters` to learn the difference. In short,
Image.draft() return value Image.draft() return value
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
If the :py:meth:`~PIL.Image.Image.draft` method has no effect, it returns ``None``. If the :py:meth:`~PIL.Image.Image.draft` method has no effect, it returns :data:`None`.
If it does have an effect, then it previously returned the image itself. If it does have an effect, then it previously returned the image itself.
However, unlike other `chain methods`_, :py:meth:`~PIL.Image.Image.draft` does not However, unlike other `chain methods`_, :py:meth:`~PIL.Image.Image.draft` does not
return a modified version of the image, but modifies it in-place. So instead, if return a modified version of the image, but modifies it in-place. So instead, if
@ -95,7 +95,7 @@ the closer the result to the fair resampling. The smaller ``reducing_gap``,
the faster resizing. With ``reducing_gap`` greater or equal to 3.0, the faster resizing. With ``reducing_gap`` greater or equal to 3.0,
the result is indistinguishable from fair resampling. the result is indistinguishable from fair resampling.
The default value for :py:meth:`~PIL.Image.Image.resize` is ``None``, The default value for :py:meth:`~PIL.Image.Image.resize` is :data:`None`,
which means that the optimization is turned off by default. which means that the optimization is turned off by default.
The default value for :py:meth:`~PIL.Image.Image.thumbnail` is 2.0, The default value for :py:meth:`~PIL.Image.Image.thumbnail` is 2.0,

View File

@ -63,7 +63,7 @@ Support has been added for ``ImageGrab.grab()`` on Linux using the X server
with the XCB library. with the XCB library.
An optional ``xdisplay`` parameter has been added to select the X server, An optional ``xdisplay`` parameter has been added to select the X server,
with the default value of ``None`` using the default X server. with the default value of :data:`None` using the default X server.
Passing a different value on Windows or macOS will force taking a snapshot Passing a different value on Windows or macOS will force taking a snapshot
using the selected X server; pass an empty string to use the default X server. using the selected X server; pass an empty string to use the default X server.

View File

@ -43,6 +43,13 @@ Image.show command parameter
The ``command`` parameter was deprecated and will be removed in a future release. The ``command`` parameter was deprecated and will be removed in a future release.
Use a subclass of :py:class:`PIL.ImageShow.Viewer` instead. Use a subclass of :py:class:`PIL.ImageShow.Viewer` instead.
Image._showxv
~~~~~~~~~~~~~
``Image._showxv`` has been deprecated. Use :py:meth:`~PIL.Image.Image.show`
instead. If custom behaviour is required, use :py:meth:`~PIL.ImageShow.register` to add
a custom :py:class:`~PIL.ImageShow.Viewer` class.
ImageFile.raise_ioerror ImageFile.raise_ioerror
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1,6 +1,13 @@
Release Notes Release Notes
============= =============
Pillow is released quarterly on January 2nd, April 1st, July 1st and October 15th.
Patch releases are created if the latest release contains severe bugs, or if security
fixes are put together before a scheduled release.
Please use the latest version of Pillow. Functionality and security fixes should not be
expected to be backported to earlier versions.
.. note:: Contributors please include release notes as needed or appropriate with your bug fixes, feature additions and tests. .. note:: Contributors please include release notes as needed or appropriate with your bug fixes, feature additions and tests.
.. toctree:: .. toctree::

View File

@ -1,5 +1,5 @@
# Development, documentation & testing requirements. # Development, documentation & testing requirements.
black; python_version >= '3.6' black
check-manifest check-manifest
coverage coverage
jarn.viewdoc jarn.viewdoc
@ -9,4 +9,6 @@ pyflakes
pyroma pyroma
pytest pytest
pytest-cov pytest-cov
sphinx>=2.4
sphinx-removed-in
sphinx-rtd-theme sphinx-rtd-theme

View File

@ -9,5 +9,5 @@ line_length = 88
multi_line_output = 3 multi_line_output = 3
[tool:pytest] [tool:pytest]
addopts = -rs addopts = -ra --color=yes
testpaths = Tests testpaths = Tests

View File

@ -880,7 +880,6 @@ try:
"Development Status :: 6 - Mature", "Development Status :: 6 - Mature",
"License :: OSI Approved :: Historical Permission Notice and Disclaimer (HPND)", # noqa: E501 "License :: OSI Approved :: Historical Permission Notice and Disclaimer (HPND)", # noqa: E501
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.8",
@ -893,7 +892,7 @@ try:
"Topic :: Multimedia :: Graphics :: Graphics Conversion", "Topic :: Multimedia :: Graphics :: Graphics Conversion",
"Topic :: Multimedia :: Graphics :: Viewers", "Topic :: Multimedia :: Graphics :: Viewers",
], ],
python_requires=">=3.5", python_requires=">=3.6",
cmdclass={"build_ext": pil_build_ext}, cmdclass={"build_ext": pil_build_ext},
ext_modules=[Extension("PIL._imaging", ["_imaging.c"])], ext_modules=[Extension("PIL._imaging", ["_imaging.c"])],
include_package_data=True, include_package_data=True,

View File

@ -17,13 +17,13 @@
# See the README file for information on usage and redistribution. # See the README file for information on usage and redistribution.
# #
"""
Parse X Bitmap Distribution Format (BDF)
"""
from . import FontFile, Image from . import FontFile, Image
# --------------------------------------------------------------------
# parse X Bitmap Distribution Format (BDF)
# --------------------------------------------------------------------
bdf_slant = { bdf_slant = {
"R": "Roman", "R": "Roman",
"I": "Italic", "I": "Italic",
@ -78,11 +78,9 @@ def bdf_char(f):
return id, int(props["ENCODING"]), bbox, im return id, int(props["ENCODING"]), bbox, im
##
# Font file plugin for the X11 BDF format.
class BdfFontFile(FontFile.FontFile): class BdfFontFile(FontFile.FontFile):
"""Font file plugin for the X11 BDF format."""
def __init__(self, fp): def __init__(self, fp):
super().__init__() super().__init__()

View File

@ -282,8 +282,8 @@ class _BLPBaseDecoder(ImageFile.PyDecoder):
self.magic = self.fd.read(4) self.magic = self.fd.read(4)
self._read_blp_header() self._read_blp_header()
self._load() self._load()
except struct.error: except struct.error as e:
raise OSError("Truncated Blp file") raise OSError("Truncated Blp file") from e
return 0, 0 return 0, 0
def _read_palette(self): def _read_palette(self):

View File

@ -304,8 +304,8 @@ def _dib_save(im, fp, filename):
def _save(im, fp, filename, bitmap_header=True): def _save(im, fp, filename, bitmap_header=True):
try: try:
rawmode, bits, colors = SAVE[im.mode] rawmode, bits, colors = SAVE[im.mode]
except KeyError: except KeyError as e:
raise OSError("cannot write mode %s as BMP" % im.mode) raise OSError("cannot write mode %s as BMP" % im.mode) from e
info = im.encoderinfo info = im.encoderinfo

View File

@ -14,14 +14,16 @@
# See the README file for information on usage and redistribution. # See the README file for information on usage and redistribution.
# #
##
# A file object that provides read access to a part of an existing
# file (for example a TAR file).
import io import io
class ContainerIO: class ContainerIO:
"""
A file object that provides read access to a part of an existing
file (for example a TAR file).
"""
def __init__(self, file, offset, length): def __init__(self, file, offset, length):
""" """
Create file object. Create file object.

View File

@ -191,7 +191,7 @@ def _accept(prefix):
## ##
# Image plugin for Encapsulated Postscript. This plugin supports only # Image plugin for Encapsulated PostScript. This plugin supports only
# a few variants of this format. # a few variants of this format.
@ -231,8 +231,8 @@ class EpsImageFile(ImageFile.ImageFile):
try: try:
m = split.match(s) m = split.match(s)
except re.error: except re.error as e:
raise SyntaxError("not an EPS file") raise SyntaxError("not an EPS file") from e
if m: if m:
k, v = m.group(1, 2) k, v = m.group(1, 2)
@ -262,7 +262,7 @@ class EpsImageFile(ImageFile.ImageFile):
else: else:
self.info[k] = "" self.info[k] = ""
elif s[0] == "%": elif s[0] == "%":
# handle non-DSC Postscript comments that some # handle non-DSC PostScript comments that some
# tools mistakenly put in the Comments section # tools mistakenly put in the Comments section
pass pass
else: else:
@ -352,7 +352,7 @@ def _save(im, fp, filename, eps=1):
im.load() im.load()
# #
# determine postscript image mode # determine PostScript image mode
if im.mode == "L": if im.mode == "L":
operator = (8, 1, "image") operator = (8, 1, "image")
elif im.mode == "RGB": elif im.mode == "RGB":

View File

@ -9,13 +9,11 @@
# See the README file for information on usage and redistribution. # See the README file for information on usage and redistribution.
# #
## """
# This module provides constants and clear-text names for various This module provides constants and clear-text names for various
# well-known EXIF tags. well-known EXIF tags.
## """
##
# Maps EXIF tags to tag names.
TAGS = { TAGS = {
# possibly incomplete # possibly incomplete
@ -280,9 +278,8 @@ TAGS = {
0xC74E: "OpcodeList3", 0xC74E: "OpcodeList3",
0xC761: "NoiseProfile", 0xC761: "NoiseProfile",
} }
"""Maps EXIF tags to tag names."""
##
# Maps EXIF GPS tags to tag names.
GPSTAGS = { GPSTAGS = {
0: "GPSVersionID", 0: "GPSVersionID",
@ -318,3 +315,4 @@ GPSTAGS = {
30: "GPSDifferential", 30: "GPSDifferential",
31: "GPSHPositioningError", 31: "GPSHPositioningError",
} }
"""Maps EXIF GPS tags to tag names."""

View File

@ -23,18 +23,15 @@ WIDTH = 800
def puti16(fp, values): def puti16(fp, values):
# write network order (big-endian) 16-bit sequence """Write network order (big-endian) 16-bit sequence"""
for v in values: for v in values:
if v < 0: if v < 0:
v += 65536 v += 65536
fp.write(_binary.o16be(v)) fp.write(_binary.o16be(v))
##
# Base class for raster font file handlers.
class FontFile: class FontFile:
"""Base class for raster font file handlers."""
bitmap = None bitmap = None

View File

@ -59,8 +59,8 @@ class FpxImageFile(ImageFile.ImageFile):
try: try:
self.ole = olefile.OleFileIO(self.fp) self.ole = olefile.OleFileIO(self.fp)
except OSError: except OSError as e:
raise SyntaxError("not an FPX file; invalid OLE file") raise SyntaxError("not an FPX file; invalid OLE file") from e
if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B": if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B":
raise SyntaxError("not an FPX file; bad root CLSID") raise SyntaxError("not an FPX file; bad root CLSID")

View File

@ -14,26 +14,30 @@
# #
# NOTE: This format cannot be automatically recognized, so the """
# class is not registered for use with Image.open(). To open a .. note::
# gd file, use the GdImageFile.open() function instead. This format cannot be automatically recognized, so the
class is not registered for use with :py:func:`PIL.Image.open()`. To open a
gd file, use the :py:func:`PIL.GdImageFile.open()` function instead.
# THE GD FORMAT IS NOT DESIGNED FOR DATA INTERCHANGE. This .. warning::
# implementation is provided for convenience and demonstrational THE GD FORMAT IS NOT DESIGNED FOR DATA INTERCHANGE. This
# purposes only. implementation is provided for convenience and demonstrational
purposes only.
"""
from . import ImageFile, ImagePalette, UnidentifiedImageError from . import ImageFile, ImagePalette, UnidentifiedImageError
from ._binary import i8, i16be as i16, i32be as i32 from ._binary import i8, i16be as i16, i32be as i32
##
# Image plugin for the GD uncompressed format. Note that this format
# is not supported by the standard <b>Image.open</b> function. To use
# this plugin, you have to import the <b>GdImageFile</b> module and
# use the <b>GdImageFile.open</b> function.
class GdImageFile(ImageFile.ImageFile): class GdImageFile(ImageFile.ImageFile):
"""
Image plugin for the GD uncompressed format. Note that this format
is not supported by the standard :py:func:`PIL.Image.open()` function. To use
this plugin, you have to import the :py:mod:`PIL.GdImageFile` module and
use the :py:func:`PIL.GdImageFile.open()` function.
"""
format = "GD" format = "GD"
format_description = "GD uncompressed images" format_description = "GD uncompressed images"
@ -81,5 +85,5 @@ def open(fp, mode="r"):
try: try:
return GdImageFile(fp) return GdImageFile(fp)
except SyntaxError: except SyntaxError as e:
raise UnidentifiedImageError("cannot identify this image file") raise UnidentifiedImageError("cannot identify this image file") from e

View File

@ -130,9 +130,9 @@ class GifImageFile(ImageFile.ImageFile):
for f in range(self.__frame + 1, frame + 1): for f in range(self.__frame + 1, frame + 1):
try: try:
self._seek(f) self._seek(f)
except EOFError: except EOFError as e:
self.seek(last_frame) self.seek(last_frame)
raise EOFError("no more images in GIF file") raise EOFError("no more images in GIF file") from e
def _seek(self, frame): def _seek(self, frame):

View File

@ -13,17 +13,19 @@
# See the README file for information on usage and redistribution. # See the README file for information on usage and redistribution.
# #
"""
Stuff to translate curve segments to palette values (derived from
the corresponding code in GIMP, written by Federico Mena Quintero.
See the GIMP distribution for more information.)
"""
from math import log, pi, sin, sqrt from math import log, pi, sin, sqrt
from ._binary import o8 from ._binary import o8
# --------------------------------------------------------------------
# Stuff to translate curve segments to palette values (derived from
# the corresponding code in GIMP, written by Federico Mena Quintero.
# See the GIMP distribution for more information.)
#
EPSILON = 1e-10 EPSILON = 1e-10
"""""" # Enable auto-doc for data member
def linear(middle, pos): def linear(middle, pos):
@ -58,6 +60,7 @@ def sphere_decreasing(middle, pos):
SEGMENTS = [linear, curved, sine, sphere_increasing, sphere_decreasing] SEGMENTS = [linear, curved, sine, sphere_increasing, sphere_decreasing]
"""""" # Enable auto-doc for data member
class GradientFile: class GradientFile:
@ -98,11 +101,9 @@ class GradientFile:
return b"".join(palette), "RGBA" return b"".join(palette), "RGBA"
##
# File handler for GIMP's gradient format.
class GimpGradientFile(GradientFile): class GimpGradientFile(GradientFile):
"""File handler for GIMP's gradient format."""
def __init__(self, fp): def __init__(self, fp):
if fp.readline()[:13] != b"GIMP Gradient": if fp.readline()[:13] != b"GIMP Gradient":

View File

@ -18,11 +18,9 @@ import re
from ._binary import o8 from ._binary import o8
##
# File handler for GIMP's palette format.
class GimpPaletteFile: class GimpPaletteFile:
"""File handler for GIMP's palette format."""
rawmode = "RGB" rawmode = "RGB"

View File

@ -337,6 +337,10 @@ def _save(im, fp, filename):
# iconutil -c icns -o {} {} # iconutil -c icns -o {} {}
fp_only = not filename
if fp_only:
f, filename = tempfile.mkstemp(".icns")
os.close(f)
convert_cmd = ["iconutil", "-c", "icns", "-o", filename, iconset] convert_cmd = ["iconutil", "-c", "icns", "-o", filename, iconset]
convert_proc = subprocess.Popen( convert_proc = subprocess.Popen(
convert_cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL convert_cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL
@ -349,6 +353,10 @@ def _save(im, fp, filename):
if retcode: if retcode:
raise subprocess.CalledProcessError(retcode, convert_cmd) raise subprocess.CalledProcessError(retcode, convert_cmd)
if fp_only:
with open(filename, "rb") as f:
fp.write(f.read())
Image.register_open(IcnsImageFile.format, IcnsImageFile, lambda x: x[:4] == b"icns") Image.register_open(IcnsImageFile.format, IcnsImageFile, lambda x: x[:4] == b"icns")
Image.register_extension(IcnsImageFile.format, ".icns") Image.register_extension(IcnsImageFile.format, ".icns")

View File

@ -163,8 +163,8 @@ class ImImageFile(ImageFile.ImageFile):
try: try:
m = split.match(s) m = split.match(s)
except re.error: except re.error as e:
raise SyntaxError("not an IM file") raise SyntaxError("not an IM file") from e
if m: if m:
@ -341,8 +341,8 @@ def _save(im, fp, filename):
try: try:
image_type, rawmode = SAVE[im.mode] image_type, rawmode = SAVE[im.mode]
except KeyError: except KeyError as e:
raise ValueError("Cannot save %s images as IM" % im.mode) raise ValueError("Cannot save %s images as IM" % im.mode) from e
frames = im.encoderinfo.get("frames", 1) frames = im.encoderinfo.get("frames", 1)

View File

@ -81,7 +81,7 @@ class DecompressionBombError(Exception):
pass pass
# Limit to around a quarter gigabyte for a 24 bit (3 bpp) image # Limit to around a quarter gigabyte for a 24-bit (3 bpp) image
MAX_IMAGE_PIXELS = int(1024 * 1024 * 1024 // 4 // 3) MAX_IMAGE_PIXELS = int(1024 * 1024 * 1024 // 4 // 3)
@ -434,8 +434,8 @@ def _getdecoder(mode, decoder_name, args, extra=()):
try: try:
# get decoder # get decoder
decoder = getattr(core, decoder_name + "_decoder") decoder = getattr(core, decoder_name + "_decoder")
except AttributeError: except AttributeError as e:
raise OSError("decoder %s not available" % decoder_name) raise OSError("decoder %s not available" % decoder_name) from e
return decoder(mode, *args + extra) return decoder(mode, *args + extra)
@ -457,8 +457,8 @@ def _getencoder(mode, encoder_name, args, extra=()):
try: try:
# get encoder # get encoder
encoder = getattr(core, encoder_name + "_encoder") encoder = getattr(core, encoder_name + "_encoder")
except AttributeError: except AttributeError as e:
raise OSError("encoder %s not available" % encoder_name) raise OSError("encoder %s not available" % encoder_name) from e
return encoder(mode, *args + extra) return encoder(mode, *args + extra)
@ -717,7 +717,7 @@ class Image:
:param encoder_name: What encoder to use. The default is to :param encoder_name: What encoder to use. The default is to
use the standard "raw" encoder. use the standard "raw" encoder.
:param args: Extra arguments to the encoder. :param args: Extra arguments to the encoder.
:rtype: A bytes object. :returns: A :py:class:`bytes` object.
""" """
# may pass tuple instead of argument list # may pass tuple instead of argument list
@ -876,7 +876,7 @@ class Image:
The default method of converting a greyscale ("L") or "RGB" The default method of converting a greyscale ("L") or "RGB"
image into a bilevel (mode "1") image uses Floyd-Steinberg image into a bilevel (mode "1") image uses Floyd-Steinberg
dither to approximate the original image luminosity levels. If dither to approximate the original image luminosity levels. If
dither is NONE, all values larger than 128 are set to 255 (white), dither is :data:`NONE`, all values larger than 128 are set to 255 (white),
all other values to 0 (black). To use other thresholds, use the all other values to 0 (black). To use other thresholds, use the
:py:meth:`~PIL.Image.Image.point` method. :py:meth:`~PIL.Image.Image.point` method.
@ -889,11 +889,11 @@ class Image:
should be 4- or 12-tuple containing floating point values. should be 4- or 12-tuple containing floating point values.
:param dither: Dithering method, used when converting from :param dither: Dithering method, used when converting from
mode "RGB" to "P" or from "RGB" or "L" to "1". mode "RGB" to "P" or from "RGB" or "L" to "1".
Available methods are NONE or FLOYDSTEINBERG (default). Available methods are :data:`NONE` or :data:`FLOYDSTEINBERG` (default).
Note that this is not used when **matrix** is supplied. Note that this is not used when **matrix** is supplied.
:param palette: Palette to use when converting from mode "RGB" :param palette: Palette to use when converting from mode "RGB"
to "P". Available palettes are WEB or ADAPTIVE. to "P". Available palettes are :data:`WEB` or :data:`ADAPTIVE`.
:param colors: Number of colors to use for the ADAPTIVE palette. :param colors: Number of colors to use for the :data:`ADAPTIVE` palette.
Defaults to 256. Defaults to 256.
:rtype: :py:class:`~PIL.Image.Image` :rtype: :py:class:`~PIL.Image.Image`
:returns: An :py:class:`~PIL.Image.Image` object. :returns: An :py:class:`~PIL.Image.Image` object.
@ -971,10 +971,10 @@ class Image:
if isinstance(t, tuple): if isinstance(t, tuple):
try: try:
t = trns_im.palette.getcolor(t) t = trns_im.palette.getcolor(t)
except Exception: except Exception as e:
raise ValueError( raise ValueError(
"Couldn't allocate a palette color for transparency" "Couldn't allocate a palette color for transparency"
) ) from e
trns_im.putpixel((0, 0), t) trns_im.putpixel((0, 0), t)
if mode in ("L", "RGB"): if mode in ("L", "RGB"):
@ -1027,8 +1027,8 @@ class Image:
# normalize source image and try again # normalize source image and try again
im = self.im.convert(getmodebase(self.mode)) im = self.im.convert(getmodebase(self.mode))
im = im.convert(mode, dither) im = im.convert(mode, dither)
except KeyError: except KeyError as e:
raise ValueError("illegal conversion") raise ValueError("illegal conversion") from e
new_im = self._new(im) new_im = self._new(im)
if delete_trns: if delete_trns:
@ -1051,10 +1051,10 @@ class Image:
of colors. of colors.
:param colors: The desired number of colors, <= 256 :param colors: The desired number of colors, <= 256
:param method: ``Image.MEDIANCUT=0`` (median cut), :param method: :data:`MEDIANCUT` (median cut),
``Image.MAXCOVERAGE=1`` (maximum coverage), :data:`MAXCOVERAGE` (maximum coverage),
``Image.FASTOCTREE=2`` (fast octree), :data:`FASTOCTREE` (fast octree),
``Image.LIBIMAGEQUANT=3`` (libimagequant; check support using :data:`LIBIMAGEQUANT` (libimagequant; check support using
:py:func:`PIL.features.check_feature` :py:func:`PIL.features.check_feature`
with ``feature="libimagequant"``). with ``feature="libimagequant"``).
:param kmeans: Integer :param kmeans: Integer
@ -1062,7 +1062,7 @@ class Image:
:py:class:`PIL.Image.Image`. :py:class:`PIL.Image.Image`.
:param dither: Dithering method, used when converting from :param dither: Dithering method, used when converting from
mode "RGB" to "P" or from "RGB" or "L" to "1". mode "RGB" to "P" or from "RGB" or "L" to "1".
Available methods are NONE or FLOYDSTEINBERG (default). Available methods are :data:`NONE` or :data:`FLOYDSTEINBERG` (default).
Default: 1 (legacy setting) Default: 1 (legacy setting)
:returns: A new image :returns: A new image
@ -1577,6 +1577,13 @@ class Image:
single argument. The function is called once for each single argument. The function is called once for each
possible pixel value, and the resulting table is applied to possible pixel value, and the resulting table is applied to
all bands of the image. all bands of the image.
It may also be an :py:class:`~PIL.Image.ImagePointHandler`
object::
class Example(Image.ImagePointHandler):
def point(self, data):
# Return result
:param mode: Output mode (default is same as input). In the :param mode: Output mode (default is same as input). In the
current version, this can only be used if the source image current version, this can only be used if the source image
has mode "L" or "P", and the output has mode "1" or the has mode "L" or "P", and the output has mode "1" or the
@ -1625,16 +1632,16 @@ class Image:
mode = getmodebase(self.mode) + "A" mode = getmodebase(self.mode) + "A"
try: try:
self.im.setmode(mode) self.im.setmode(mode)
except (AttributeError, ValueError): except (AttributeError, ValueError) as e:
# do things the hard way # do things the hard way
im = self.im.convert(mode) im = self.im.convert(mode)
if im.mode not in ("LA", "PA", "RGBA"): if im.mode not in ("LA", "PA", "RGBA"):
raise ValueError # sanity check raise ValueError from e # sanity check
self.im = im self.im = im
self.pyaccess = None self.pyaccess = None
self.mode = self.im.mode self.mode = self.im.mode
except (KeyError, ValueError): except (KeyError, ValueError) as e:
raise ValueError("illegal image mode") raise ValueError("illegal image mode") from e
if self.mode in ("LA", "PA"): if self.mode in ("LA", "PA"):
band = 1 band = 1
@ -1842,12 +1849,12 @@ class Image:
:param size: The requested size in pixels, as a 2-tuple: :param size: The requested size in pixels, as a 2-tuple:
(width, height). (width, height).
:param resample: An optional resampling filter. This can be :param resample: An optional resampling filter. This can be
one of :py:attr:`PIL.Image.NEAREST`, :py:attr:`PIL.Image.BOX`, one of :py:data:`PIL.Image.NEAREST`, :py:data:`PIL.Image.BOX`,
:py:attr:`PIL.Image.BILINEAR`, :py:attr:`PIL.Image.HAMMING`, :py:data:`PIL.Image.BILINEAR`, :py:data:`PIL.Image.HAMMING`,
:py:attr:`PIL.Image.BICUBIC` or :py:attr:`PIL.Image.LANCZOS`. :py:data:`PIL.Image.BICUBIC` or :py:data:`PIL.Image.LANCZOS`.
Default filter is :py:attr:`PIL.Image.BICUBIC`. Default filter is :py:data:`PIL.Image.BICUBIC`.
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:data:`PIL.Image.NEAREST`.
See: :ref:`concept-filters`. See: :ref:`concept-filters`.
:param box: An optional 4-tuple of floats providing :param box: An optional 4-tuple of floats providing
the source image region to be scaled. the source image region to be scaled.
@ -1977,12 +1984,12 @@ class Image:
:param angle: In degrees counter clockwise. :param angle: In degrees counter clockwise.
:param resample: An optional resampling filter. This can be :param resample: An optional resampling filter. This can be
one of :py:attr:`PIL.Image.NEAREST` (use nearest neighbour), one of :py:data:`PIL.Image.NEAREST` (use nearest neighbour),
:py:attr:`PIL.Image.BILINEAR` (linear interpolation in a 2x2 :py:data:`PIL.Image.BILINEAR` (linear interpolation in a 2x2
environment), or :py:attr:`PIL.Image.BICUBIC` environment), or :py:data:`PIL.Image.BICUBIC`
(cubic spline interpolation in a 4x4 environment). (cubic spline interpolation in a 4x4 environment).
If omitted, or if the image has mode "1" or "P", it is If omitted, or if the image has mode "1" or "P", it is
set to :py:attr:`PIL.Image.NEAREST`. See :ref:`concept-filters`. set to :py:data:`PIL.Image.NEAREST`. See :ref:`concept-filters`.
:param expand: Optional expansion flag. If true, expands the output :param expand: Optional expansion flag. If true, expands the output
image to make it large enough to hold the entire rotated image. image to make it large enough to hold the entire rotated image.
If false or omitted, make the output image the same size as the If false or omitted, make the output image the same size as the
@ -2136,8 +2143,8 @@ class Image:
init() init()
try: try:
format = EXTENSION[ext] format = EXTENSION[ext]
except KeyError: except KeyError as e:
raise ValueError("unknown file extension: {}".format(ext)) raise ValueError("unknown file extension: {}".format(ext)) from e
if format.upper() not in SAVE: if format.upper() not in SAVE:
init() init()
@ -2170,6 +2177,9 @@ class Image:
See :py:meth:`~PIL.Image.Image.tell`. See :py:meth:`~PIL.Image.Image.tell`.
If defined, :attr:`~PIL.Image.Image.n_frames` refers to the
number of available frames.
:param frame: Frame number, starting at 0. :param frame: Frame number, starting at 0.
:exception EOFError: If the call attempts to seek beyond the end :exception EOFError: If the call attempts to seek beyond the end
of the sequence. of the sequence.
@ -2245,8 +2255,8 @@ class Image:
if isinstance(channel, str): if isinstance(channel, str):
try: try:
channel = self.getbands().index(channel) channel = self.getbands().index(channel)
except ValueError: except ValueError as e:
raise ValueError('The image has no channel "{}"'.format(channel)) raise ValueError('The image has no channel "{}"'.format(channel)) from e
return self._new(self.im.getband(channel)) return self._new(self.im.getband(channel))
@ -2254,6 +2264,9 @@ class Image:
""" """
Returns the current frame number. See :py:meth:`~PIL.Image.Image.seek`. Returns the current frame number. See :py:meth:`~PIL.Image.Image.seek`.
If defined, :attr:`~PIL.Image.Image.n_frames` refers to the
number of available frames.
:returns: Frame number, starting with 0. :returns: Frame number, starting with 0.
""" """
return 0 return 0
@ -2274,10 +2287,10 @@ class Image:
:param size: Requested size. :param size: Requested size.
:param resample: Optional resampling filter. This can be one :param resample: Optional resampling filter. This can be one
of :py:attr:`PIL.Image.NEAREST`, :py:attr:`PIL.Image.BILINEAR`, of :py:data:`PIL.Image.NEAREST`, :py:data:`PIL.Image.BILINEAR`,
:py:attr:`PIL.Image.BICUBIC`, or :py:attr:`PIL.Image.LANCZOS`. :py:data:`PIL.Image.BICUBIC`, or :py:data:`PIL.Image.LANCZOS`.
If omitted, it defaults to :py:attr:`PIL.Image.BICUBIC`. If omitted, it defaults to :py:data:`PIL.Image.BICUBIC`.
(was :py:attr:`PIL.Image.NEAREST` prior to version 2.5.0). (was :py:data:`PIL.Image.NEAREST` prior to version 2.5.0).
See: :ref:`concept-filters`. See: :ref:`concept-filters`.
: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 by integer times in two steps. First, reducing the image by integer times
@ -2341,21 +2354,21 @@ class Image:
:param size: The output size. :param size: The output size.
:param method: The transformation method. This is one of :param method: The transformation method. This is one of
:py:attr:`PIL.Image.EXTENT` (cut out a rectangular subregion), :py:data:`PIL.Image.EXTENT` (cut out a rectangular subregion),
:py:attr:`PIL.Image.AFFINE` (affine transform), :py:data:`PIL.Image.AFFINE` (affine transform),
:py:attr:`PIL.Image.PERSPECTIVE` (perspective transform), :py:data:`PIL.Image.PERSPECTIVE` (perspective transform),
:py:attr:`PIL.Image.QUAD` (map a quadrilateral to a rectangle), or :py:data:`PIL.Image.QUAD` (map a quadrilateral to a rectangle), or
:py:attr:`PIL.Image.MESH` (map a number of source quadrilaterals :py:data:`PIL.Image.MESH` (map a number of source quadrilaterals
in one operation). in one operation).
It may also be an :py:class:`~PIL.Image.ImageTransformHandler` It may also be an :py:class:`~PIL.Image.ImageTransformHandler`
object:: object::
class Example(Image.ImageTransformHandler): class Example(Image.ImageTransformHandler):
def transform(size, method, data, resample, fill=1): def transform(self, size, data, resample, fill=1):
# Return result # Return result
It may also be an object with a :py:meth:`~method.getdata` method It may also be an object with a ``method.getdata`` method
that returns a tuple supplying new **method** and **data** values:: that returns a tuple supplying new **method** and **data** values::
class Example: class Example:
@ -2365,11 +2378,11 @@ class Image:
return method, data return method, data
:param data: Extra data to the transformation method. :param data: Extra data to the transformation method.
:param resample: Optional resampling filter. It can be one of :param resample: Optional resampling filter. It can be one of
:py:attr:`PIL.Image.NEAREST` (use nearest neighbour), :py:data:`PIL.Image.NEAREST` (use nearest neighbour),
:py:attr:`PIL.Image.BILINEAR` (linear interpolation in a 2x2 :py:data:`PIL.Image.BILINEAR` (linear interpolation in a 2x2
environment), or :py:attr:`PIL.Image.BICUBIC` (cubic spline environment), or :py:data:`PIL.Image.BICUBIC` (cubic spline
interpolation in a 4x4 environment). If omitted, or if the image interpolation in a 4x4 environment). If omitted, or if the image
has mode "1" or "P", it is set to :py:attr:`PIL.Image.NEAREST`. has mode "1" or "P", it is set to :py:data:`PIL.Image.NEAREST`.
See: :ref:`concept-filters`. See: :ref:`concept-filters`.
:param fill: If **method** is an :param fill: If **method** is an
:py:class:`~PIL.Image.ImageTransformHandler` object, this is one of :py:class:`~PIL.Image.ImageTransformHandler` object, this is one of
@ -2493,10 +2506,10 @@ class Image:
""" """
Transpose image (flip or rotate in 90 degree steps) Transpose image (flip or rotate in 90 degree steps)
:param method: One of :py:attr:`PIL.Image.FLIP_LEFT_RIGHT`, :param method: One of :py:data:`PIL.Image.FLIP_LEFT_RIGHT`,
:py:attr:`PIL.Image.FLIP_TOP_BOTTOM`, :py:attr:`PIL.Image.ROTATE_90`, :py:data:`PIL.Image.FLIP_TOP_BOTTOM`, :py:data:`PIL.Image.ROTATE_90`,
:py:attr:`PIL.Image.ROTATE_180`, :py:attr:`PIL.Image.ROTATE_270`, :py:data:`PIL.Image.ROTATE_180`, :py:data:`PIL.Image.ROTATE_270`,
:py:attr:`PIL.Image.TRANSPOSE` or :py:attr:`PIL.Image.TRANSVERSE`. :py:data:`PIL.Image.TRANSPOSE` or :py:data:`PIL.Image.TRANSVERSE`.
:returns: Returns a flipped or rotated copy of this image. :returns: Returns a flipped or rotated copy of this image.
""" """
@ -2534,12 +2547,20 @@ class Image:
class ImagePointHandler: class ImagePointHandler:
# used as a mixin by point transforms (for use with im.point) """
Used as a mixin by point transforms
(for use with :py:meth:`~PIL.Image.Image.point`)
"""
pass pass
class ImageTransformHandler: class ImageTransformHandler:
# used as a mixin by geometry transforms (for use with im.transform) """
Used as a mixin by geometry transforms
(for use with :py:meth:`~PIL.Image.Image.transform`)
"""
pass pass
@ -2743,12 +2764,12 @@ def fromarray(obj, mode=None):
if mode is None: if mode is None:
try: try:
typekey = (1, 1) + shape[2:], arr["typestr"] typekey = (1, 1) + shape[2:], arr["typestr"]
except KeyError: except KeyError as e:
raise TypeError("Cannot handle this data type") raise TypeError("Cannot handle this data type") from e
try: try:
mode, rawmode = _fromarray_typemap[typekey] mode, rawmode = _fromarray_typemap[typekey]
except KeyError: except KeyError as e:
raise TypeError("Cannot handle this data type: %s, %s" % typekey) raise TypeError("Cannot handle this data type: %s, %s" % typekey) from e
else: else:
rawmode = mode rawmode = mode
if mode in ["1", "L", "I", "P", "F"]: if mode in ["1", "L", "I", "P", "F"]:
@ -2847,8 +2868,8 @@ def open(fp, mode="r"):
:py:func:`~PIL.Image.new`. See :ref:`file-handling`. :py:func:`~PIL.Image.new`. See :ref:`file-handling`.
:param fp: A filename (string), pathlib.Path object or a file object. :param fp: A filename (string), pathlib.Path object or a file object.
The file object must implement :py:meth:`~file.read`, The file object must implement ``file.read``,
:py:meth:`~file.seek`, and :py:meth:`~file.tell` methods, ``file.seek``, and ``file.tell`` methods,
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.
@ -3150,12 +3171,21 @@ def register_encoder(name, encoder):
def _show(image, **options): def _show(image, **options):
options["_internal_pillow"] = True
_showxv(image, **options) _showxv(image, **options)
def _showxv(image, title=None, **options): def _showxv(image, title=None, **options):
from . import ImageShow from . import ImageShow
if "_internal_pillow" in options:
del options["_internal_pillow"]
else:
warnings.warn(
"_showxv is deprecated and will be removed in a future release. "
"Use Image.show instead.",
DeprecationWarning,
)
ImageShow.show(image, title, **options) ImageShow.show(image, title, **options)

View File

@ -293,7 +293,7 @@ def logical_xor(image1, image2):
def blend(image1, image2, alpha): def blend(image1, image2, alpha):
"""Blend images using constant transparency weight. Alias for """Blend images using constant transparency weight. Alias for
:py:meth:`PIL.Image.Image.blend`. :py:func:`PIL.Image.blend`.
:rtype: :py:class:`~PIL.Image.Image` :rtype: :py:class:`~PIL.Image.Image`
""" """
@ -303,7 +303,7 @@ def blend(image1, image2, alpha):
def composite(image1, image2, mask): def composite(image1, image2, mask):
"""Create composite using transparency mask. Alias for """Create composite using transparency mask. Alias for
:py:meth:`PIL.Image.Image.composite`. :py:func:`PIL.Image.composite`.
:rtype: :py:class:`~PIL.Image.Image` :rtype: :py:class:`~PIL.Image.Image`
""" """

View File

@ -295,11 +295,12 @@ def profileToProfile(
``inputProfile`` to ``outputProfile``. ``inputProfile`` to ``outputProfile``.
If the input or output profiles specified are not valid filenames, a If the input or output profiles specified are not valid filenames, a
``PyCMSError`` will be raised. If ``inPlace`` is ``True`` and :exc:`PyCMSError` will be raised. If ``inPlace`` is ``True`` and
``outputMode != im.mode``, a ``PyCMSError`` will be raised. If an error ``outputMode != im.mode``, a :exc:`PyCMSError` will be raised.
occurs during application of the profiles, a ``PyCMSError`` will be raised. If an error occurs during application of the profiles,
a :exc:`PyCMSError` will be raised.
If ``outputMode`` is not a mode supported by the ``outputProfile`` (or by pyCMS), If ``outputMode`` is not a mode supported by the ``outputProfile`` (or by pyCMS),
a ``PyCMSError`` will be raised. a :exc:`PyCMSError` will be raised.
This function applies an ICC transformation to im from ``inputProfile``'s This function applies an ICC transformation to im from ``inputProfile``'s
color space to ``outputProfile``'s color space using the specified rendering color space to ``outputProfile``'s color space using the specified rendering
@ -369,7 +370,7 @@ def profileToProfile(
else: else:
imOut = transform.apply(im) imOut = transform.apply(im)
except (OSError, TypeError, ValueError) as v: except (OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
return imOut return imOut
@ -381,8 +382,8 @@ def getOpenProfile(profileFilename):
The PyCMSProfile object can be passed back into pyCMS for use in creating The PyCMSProfile object can be passed back into pyCMS for use in creating
transforms and such (as in ImageCms.buildTransformFromOpenProfiles()). transforms and such (as in ImageCms.buildTransformFromOpenProfiles()).
If ``profileFilename`` is not a valid filename for an ICC profile, a ``PyCMSError`` If ``profileFilename`` is not a valid filename for an ICC profile,
will be raised. a :exc:`PyCMSError` will be raised.
:param profileFilename: String, as a valid filename path to the ICC profile :param profileFilename: String, as a valid filename path to the ICC profile
you wish to open, or a file-like object. you wish to open, or a file-like object.
@ -393,7 +394,7 @@ def getOpenProfile(profileFilename):
try: try:
return ImageCmsProfile(profileFilename) return ImageCmsProfile(profileFilename)
except (OSError, TypeError, ValueError) as v: except (OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def buildTransform( def buildTransform(
@ -410,11 +411,11 @@ def buildTransform(
image. image.
If the input or output profiles specified are not valid filenames, a If the input or output profiles specified are not valid filenames, a
``PyCMSError`` will be raised. If an error occurs during creation of the :exc:`PyCMSError` will be raised. If an error occurs during creation
transform, a ``PyCMSError`` will be raised. of the transform, a :exc:`PyCMSError` will be raised.
If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile`` If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile``
(or by pyCMS), a ``PyCMSError`` will be raised. (or by pyCMS), a :exc:`PyCMSError` will be raised.
This function builds and returns an ICC transform from the ``inputProfile`` This function builds and returns an ICC transform from the ``inputProfile``
to the ``outputProfile`` using the ``renderingIntent`` to determine what to do to the ``outputProfile`` using the ``renderingIntent`` to determine what to do
@ -474,7 +475,7 @@ def buildTransform(
inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags
) )
except (OSError, TypeError, ValueError) as v: except (OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def buildProofTransform( def buildProofTransform(
@ -493,13 +494,13 @@ def buildProofTransform(
obtained on the ``proofProfile`` device. obtained on the ``proofProfile`` device.
If the input, output, or proof profiles specified are not valid If the input, output, or proof profiles specified are not valid
filenames, a ``PyCMSError`` will be raised. filenames, a :exc:`PyCMSError` will be raised.
If an error occurs during creation of the transform, a ``PyCMSError`` If an error occurs during creation of the transform,
will be raised. a :exc:`PyCMSError` will be raised.
If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile`` If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile``
(or by pyCMS), a ``PyCMSError`` will be raised. (or by pyCMS), a :exc:`PyCMSError` will be raised.
This function builds and returns an ICC transform from the ``inputProfile`` This function builds and returns an ICC transform from the ``inputProfile``
to the ``outputProfile``, but tries to simulate the result that would be to the ``outputProfile``, but tries to simulate the result that would be
@ -585,7 +586,7 @@ def buildProofTransform(
flags, flags,
) )
except (OSError, TypeError, ValueError) as v: except (OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
buildTransformFromOpenProfiles = buildTransform buildTransformFromOpenProfiles = buildTransform
@ -596,17 +597,17 @@ def applyTransform(im, transform, inPlace=False):
""" """
(pyCMS) Applies a transform to a given image. (pyCMS) Applies a transform to a given image.
If ``im.mode != transform.inMode``, a ``PyCMSError`` is raised. If ``im.mode != transform.inMode``, a :exc:`PyCMSError` is raised.
If ``inPlace`` is ``True`` and ``transform.inMode != transform.outMode``, a If ``inPlace`` is ``True`` and ``transform.inMode != transform.outMode``, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If ``im.mode``, ``transform.inMode`` or ``transform.outMode`` is not If ``im.mode``, ``transform.inMode`` or ``transform.outMode`` is not
supported by pyCMSdll or the profiles you used for the transform, a supported by pyCMSdll or the profiles you used for the transform, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while the transform is being applied, a ``PyCMSError`` If an error occurs while the transform is being applied,
is raised. a :exc:`PyCMSError` is raised.
This function applies a pre-calculated transform (from This function applies a pre-calculated transform (from
ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles()) ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles())
@ -640,7 +641,7 @@ def applyTransform(im, transform, inPlace=False):
else: else:
imOut = transform.apply(im) imOut = transform.apply(im)
except (TypeError, ValueError) as v: except (TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
return imOut return imOut
@ -649,12 +650,14 @@ def createProfile(colorSpace, colorTemp=-1):
""" """
(pyCMS) Creates a profile. (pyCMS) Creates a profile.
If colorSpace not in ``["LAB", "XYZ", "sRGB"]``, a ``PyCMSError`` is raised. If colorSpace not in ``["LAB", "XYZ", "sRGB"]``,
a :exc:`PyCMSError` is raised.
If using LAB and ``colorTemp`` is not a positive integer, a ``PyCMSError`` is If using LAB and ``colorTemp`` is not a positive integer,
raised. a :exc:`PyCMSError` is raised.
If an error occurs while creating the profile, a ``PyCMSError`` is raised. If an error occurs while creating the profile,
a :exc:`PyCMSError` is raised.
Use this function to create common profiles on-the-fly instead of Use this function to create common profiles on-the-fly instead of
having to supply a profile on disk and knowing the path to it. It having to supply a profile on disk and knowing the path to it. It
@ -682,15 +685,15 @@ def createProfile(colorSpace, colorTemp=-1):
if colorSpace == "LAB": if colorSpace == "LAB":
try: try:
colorTemp = float(colorTemp) colorTemp = float(colorTemp)
except (TypeError, ValueError): except (TypeError, ValueError) as e:
raise PyCMSError( raise PyCMSError(
'Color temperature must be numeric, "%s" not valid' % colorTemp 'Color temperature must be numeric, "%s" not valid' % colorTemp
) ) from e
try: try:
return core.createProfile(colorSpace, colorTemp) return core.createProfile(colorSpace, colorTemp)
except (TypeError, ValueError) as v: except (TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileName(profile): def getProfileName(profile):
@ -699,8 +702,8 @@ def getProfileName(profile):
(pyCMS) Gets the internal product name for the given profile. (pyCMS) Gets the internal product name for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, If ``profile`` isn't a valid CmsProfile object or filename to a profile,
a ``PyCMSError`` is raised If an error occurs while trying to obtain the a :exc:`PyCMSError` is raised If an error occurs while trying
name tag, a ``PyCMSError`` is raised. to obtain the name tag, a :exc:`PyCMSError` is raised.
Use this function to obtain the INTERNAL name of the profile (stored Use this function to obtain the INTERNAL name of the profile (stored
in an ICC tag in the profile itself), usually the one used when the in an ICC tag in the profile itself), usually the one used when the
@ -732,7 +735,7 @@ def getProfileName(profile):
return "{} - {}\n".format(model, manufacturer) return "{} - {}\n".format(model, manufacturer)
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileInfo(profile): def getProfileInfo(profile):
@ -740,10 +743,10 @@ def getProfileInfo(profile):
(pyCMS) Gets the internal product information for the given profile. (pyCMS) Gets the internal product information for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, If ``profile`` isn't a valid CmsProfile object or filename to a profile,
a ``PyCMSError`` is raised. a :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the info tag, a ``PyCMSError`` If an error occurs while trying to obtain the info tag,
is raised. a :exc:`PyCMSError` is raised.
Use this function to obtain the information stored in the profile's Use this function to obtain the information stored in the profile's
info tag. This often contains details about the profile, and how it info tag. This often contains details about the profile, and how it
@ -772,7 +775,7 @@ def getProfileInfo(profile):
return "\r\n\r\n".join(arr) + "\r\n\r\n" return "\r\n\r\n".join(arr) + "\r\n\r\n"
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileCopyright(profile): def getProfileCopyright(profile):
@ -780,10 +783,10 @@ def getProfileCopyright(profile):
(pyCMS) Gets the copyright for the given profile. (pyCMS) Gets the copyright for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, a If ``profile`` isn't a valid CmsProfile object or filename to a profile, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the copyright tag, a ``PyCMSError`` If an error occurs while trying to obtain the copyright tag,
is raised. a :exc:`PyCMSError` is raised.
Use this function to obtain the information stored in the profile's Use this function to obtain the information stored in the profile's
copyright tag. copyright tag.
@ -800,7 +803,7 @@ def getProfileCopyright(profile):
profile = ImageCmsProfile(profile) profile = ImageCmsProfile(profile)
return (profile.profile.copyright or "") + "\n" return (profile.profile.copyright or "") + "\n"
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileManufacturer(profile): def getProfileManufacturer(profile):
@ -808,10 +811,10 @@ def getProfileManufacturer(profile):
(pyCMS) Gets the manufacturer for the given profile. (pyCMS) Gets the manufacturer for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, a If ``profile`` isn't a valid CmsProfile object or filename to a profile, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the manufacturer tag, a If an error occurs while trying to obtain the manufacturer tag, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
Use this function to obtain the information stored in the profile's Use this function to obtain the information stored in the profile's
manufacturer tag. manufacturer tag.
@ -828,7 +831,7 @@ def getProfileManufacturer(profile):
profile = ImageCmsProfile(profile) profile = ImageCmsProfile(profile)
return (profile.profile.manufacturer or "") + "\n" return (profile.profile.manufacturer or "") + "\n"
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileModel(profile): def getProfileModel(profile):
@ -836,10 +839,10 @@ def getProfileModel(profile):
(pyCMS) Gets the model for the given profile. (pyCMS) Gets the model for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, a If ``profile`` isn't a valid CmsProfile object or filename to a profile, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the model tag, a ``PyCMSError`` If an error occurs while trying to obtain the model tag,
is raised. a :exc:`PyCMSError` is raised.
Use this function to obtain the information stored in the profile's Use this function to obtain the information stored in the profile's
model tag. model tag.
@ -857,7 +860,7 @@ def getProfileModel(profile):
profile = ImageCmsProfile(profile) profile = ImageCmsProfile(profile)
return (profile.profile.model or "") + "\n" return (profile.profile.model or "") + "\n"
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileDescription(profile): def getProfileDescription(profile):
@ -865,10 +868,10 @@ def getProfileDescription(profile):
(pyCMS) Gets the description for the given profile. (pyCMS) Gets the description for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, a If ``profile`` isn't a valid CmsProfile object or filename to a profile, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the description tag, a ``PyCMSError`` If an error occurs while trying to obtain the description tag,
is raised. a :exc:`PyCMSError` is raised.
Use this function to obtain the information stored in the profile's Use this function to obtain the information stored in the profile's
description tag. description tag.
@ -886,7 +889,7 @@ def getProfileDescription(profile):
profile = ImageCmsProfile(profile) profile = ImageCmsProfile(profile)
return (profile.profile.profile_description or "") + "\n" return (profile.profile.profile_description or "") + "\n"
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getDefaultIntent(profile): def getDefaultIntent(profile):
@ -894,10 +897,10 @@ def getDefaultIntent(profile):
(pyCMS) Gets the default intent name for the given profile. (pyCMS) Gets the default intent name for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, a If ``profile`` isn't a valid CmsProfile object or filename to a profile, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the default intent, a If an error occurs while trying to obtain the default intent, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
Use this function to determine the default (and usually best optimized) Use this function to determine the default (and usually best optimized)
rendering intent for this profile. Most profiles support multiple rendering intent for this profile. Most profiles support multiple
@ -925,7 +928,7 @@ def getDefaultIntent(profile):
profile = ImageCmsProfile(profile) profile = ImageCmsProfile(profile)
return profile.profile.rendering_intent return profile.profile.rendering_intent
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def isIntentSupported(profile, intent, direction): def isIntentSupported(profile, intent, direction):
@ -940,8 +943,8 @@ def isIntentSupported(profile, intent, direction):
be used for others. Some profiles can only be used for certain be used for others. Some profiles can only be used for certain
rendering intents, so it's best to either verify this before trying rendering intents, so it's best to either verify this before trying
to create a transform with them (using this function), or catch the to create a transform with them (using this function), or catch the
potential ``PyCMSError`` that will occur if they don't support the modes potential :exc:`PyCMSError` that will occur if they don't
you select. support the modes you select.
:param profile: EITHER a valid CmsProfile object, OR a string of the :param profile: EITHER a valid CmsProfile object, OR a string of the
filename of an ICC profile. filename of an ICC profile.
@ -976,7 +979,7 @@ def isIntentSupported(profile, intent, direction):
else: else:
return -1 return -1
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def versions(): def versions():

View File

@ -16,21 +16,35 @@
# See the README file for information on usage and redistribution. # See the README file for information on usage and redistribution.
# #
"""
(Experimental) WCK-style drawing interface operations
.. seealso:: :py:mod:`PIL.ImageDraw`
"""
from . import Image, ImageColor, ImageDraw, ImageFont, ImagePath from . import Image, ImageColor, ImageDraw, ImageFont, ImagePath
class Pen: class Pen:
"""Stores an outline color and width."""
def __init__(self, color, width=1, opacity=255): def __init__(self, color, width=1, opacity=255):
self.color = ImageColor.getrgb(color) self.color = ImageColor.getrgb(color)
self.width = width self.width = width
class Brush: class Brush:
"""Stores a fill color"""
def __init__(self, color, opacity=255): def __init__(self, color, opacity=255):
self.color = ImageColor.getrgb(color) self.color = ImageColor.getrgb(color)
class Font: class Font:
"""Stores a TrueType font and color"""
def __init__(self, color, file, size=12): def __init__(self, color, file, size=12):
# FIXME: add support for bitmap fonts # FIXME: add support for bitmap fonts
self.color = ImageColor.getrgb(color) self.color = ImageColor.getrgb(color)
@ -38,6 +52,10 @@ class Font:
class Draw: class Draw:
"""
(Experimental) WCK-style drawing interface
"""
def __init__(self, image, size=None, color=None): def __init__(self, image, size=None, color=None):
if not hasattr(image, "im"): if not hasattr(image, "im"):
image = Image.new(image, size, color) image = Image.new(image, size, color)
@ -73,35 +91,89 @@ class Draw:
getattr(self.draw, op)(xy, fill=fill, outline=outline) getattr(self.draw, op)(xy, fill=fill, outline=outline)
def settransform(self, offset): def settransform(self, offset):
"""Sets a transformation offset."""
(xoffset, yoffset) = offset (xoffset, yoffset) = offset
self.transform = (1, 0, xoffset, 0, 1, yoffset) self.transform = (1, 0, xoffset, 0, 1, yoffset)
def arc(self, xy, start, end, *options): def arc(self, xy, start, end, *options):
"""
Draws an arc (a portion of a circle outline) between the start and end
angles, inside the given bounding box.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.arc`
"""
self.render("arc", xy, start, end, *options) self.render("arc", xy, start, end, *options)
def chord(self, xy, start, end, *options): def chord(self, xy, start, end, *options):
"""
Same as :py:meth:`~PIL.ImageDraw2.Draw.arc`, but connects the end points
with a straight line.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.chord`
"""
self.render("chord", xy, start, end, *options) self.render("chord", xy, start, end, *options)
def ellipse(self, xy, *options): def ellipse(self, xy, *options):
"""
Draws an ellipse inside the given bounding box.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.ellipse`
"""
self.render("ellipse", xy, *options) self.render("ellipse", xy, *options)
def line(self, xy, *options): def line(self, xy, *options):
"""
Draws a line between the coordinates in the ``xy`` list.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.line`
"""
self.render("line", xy, *options) self.render("line", xy, *options)
def pieslice(self, xy, start, end, *options): def pieslice(self, xy, start, end, *options):
"""
Same as arc, but also draws straight lines between the end points and the
center of the bounding box.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.pieslice`
"""
self.render("pieslice", xy, start, end, *options) self.render("pieslice", xy, start, end, *options)
def polygon(self, xy, *options): def polygon(self, xy, *options):
"""
Draws a polygon.
The polygon outline consists of straight lines between the given
coordinates, plus a straight line between the last and the first
coordinate.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.polygon`
"""
self.render("polygon", xy, *options) self.render("polygon", xy, *options)
def rectangle(self, xy, *options): def rectangle(self, xy, *options):
"""
Draws a rectangle.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.rectangle`
"""
self.render("rectangle", xy, *options) self.render("rectangle", xy, *options)
def text(self, xy, text, font): def text(self, xy, text, font):
"""
Draws the string at the given position.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.text`
"""
if self.transform: if self.transform:
xy = ImagePath.Path(xy) xy = ImagePath.Path(xy)
xy.transform(self.transform) xy.transform(self.transform)
self.draw.text(xy, text, font=font.font, fill=font.color) self.draw.text(xy, text, font=font.font, fill=font.color)
def textsize(self, text, font): def textsize(self, text, font):
"""
Return the size of the given string, in pixels.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.textsize`
"""
return self.draw.textsize(text, font=font.font) return self.draw.textsize(text, font=font.font)

View File

@ -85,7 +85,7 @@ def _tilesort(t):
class ImageFile(Image.Image): class ImageFile(Image.Image):
"Base class for image file format handlers." """Base class for image file format handlers."""
def __init__(self, fp=None, filename=None): def __init__(self, fp=None, filename=None):
super().__init__() super().__init__()
@ -122,7 +122,7 @@ class ImageFile(Image.Image):
EOFError, # got header but not the first frame EOFError, # got header but not the first frame
struct.error, struct.error,
) as v: ) as v:
raise SyntaxError(v) raise SyntaxError(v) from v
if not self.mode or self.size[0] <= 0: if not self.mode or self.size[0] <= 0:
raise SyntaxError("not identified by this driver") raise SyntaxError("not identified by this driver")
@ -241,12 +241,12 @@ class ImageFile(Image.Image):
while True: while True:
try: try:
s = read(self.decodermaxblock) s = read(self.decodermaxblock)
except (IndexError, struct.error): except (IndexError, struct.error) as e:
# truncated png/gif # truncated png/gif
if LOAD_TRUNCATED_IMAGES: if LOAD_TRUNCATED_IMAGES:
break break
else: else:
raise OSError("image file is truncated") raise OSError("image file is truncated") from e
if not s: # truncated jpeg if not s: # truncated jpeg
if LOAD_TRUNCATED_IMAGES: if LOAD_TRUNCATED_IMAGES:
@ -505,7 +505,7 @@ def _save(im, fp, tile, bufsize=0):
try: try:
fh = fp.fileno() fh = fp.fileno()
fp.flush() fp.flush()
except (AttributeError, io.UnsupportedOperation): except (AttributeError, io.UnsupportedOperation) as e:
# compress to Python file-compatible object # compress to Python file-compatible object
for e, b, o, a in tile: for e, b, o, a in tile:
e = Image._getencoder(im.mode, e, a, im.encoderconfig) e = Image._getencoder(im.mode, e, a, im.encoderconfig)
@ -522,7 +522,7 @@ def _save(im, fp, tile, bufsize=0):
if s: if s:
break break
if s < 0: if s < 0:
raise OSError("encoder error %d when writing image file" % s) raise OSError("encoder error %d when writing image file" % s) from e
e.cleanup() e.cleanup()
else: else:
# slight speedup: compress to real file object # slight speedup: compress to real file object

View File

@ -49,7 +49,7 @@ class Kernel(BuiltinFilter):
version, this must be (3,3) or (5,5). version, this must be (3,3) or (5,5).
:param kernel: A sequence containing kernel weights. :param kernel: A sequence containing kernel weights.
:param scale: Scale factor. If given, the result for each pixel is :param scale: Scale factor. If given, the result for each pixel is
divided by this value. the default is the sum of the divided by this value. The default is the sum of the
kernel weights. kernel weights.
:param offset: Offset. If given, this value is added to the result, :param offset: Offset. If given, this value is added to the result,
after it has been divided by the scale factor. after it has been divided by the scale factor.
@ -411,10 +411,10 @@ class Color3DLUT(MultibandFilter):
def _check_size(size): def _check_size(size):
try: try:
_, _, _ = size _, _, _ = size
except ValueError: except ValueError as e:
raise ValueError( raise ValueError(
"Size should be either an integer or a tuple of three integers." "Size should be either an integer or a tuple of three integers."
) ) from e
except TypeError: except TypeError:
size = (size, size, size) size = (size, size, size)
size = [int(x) for x in size] size = [int(x) for x in size]

Some files were not shown because too many files have changed in this diff Show More