Merge branch 'master' into python-m-pip-install

This commit is contained in:
Andrew Murray 2019-12-07 23:28:39 +11:00 committed by GitHub
commit 5dcad52a5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
241 changed files with 2735 additions and 3779 deletions

View File

@ -15,10 +15,6 @@ environment:
matrix:
- PYTHON: C:/Python38
- PYTHON: C:/Python38-x64
- PYTHON: C:/Python37
- PYTHON: C:/Python37-x64
- PYTHON: C:/Python36
- PYTHON: C:/Python36-x64
- PYTHON: C:/Python35
- PYTHON: C:/Python35-x64
- PYTHON: C:/msys64/mingw32
@ -40,11 +36,6 @@ install:
- xcopy c:\pillow-depends\*.tar.gz c:\pillow\winbuild\
- xcopy /s c:\pillow-depends\test_images\* c:\pillow\tests\images
- cd c:\pillow\winbuild\
- ps: |
if ($env:PYTHON -eq "c:/vp/pypy2")
{
c:\pillow\winbuild\appveyor_install_pypy2.cmd
}
- ps: |
if ($env:PYTHON -eq "c:/vp/pypy3")
{
@ -61,6 +52,9 @@ install:
c:\pillow\winbuild\build_deps.cmd
$host.SetShouldExit(0)
}
- curl -fsSL -o gs950.exe https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs950/gs950w32.exe
- gs950.exe /S
- path %path%;C:\Program Files (x86)\gs\gs9.50\bin
build_script:
- ps: |
@ -82,7 +76,7 @@ test_script:
- cd c:\pillow
- '%PYTHON%\%PIP_DIR%\pip.exe install pytest pytest-cov'
- c:\"Program Files (x86)"\"Windows Kits"\10\Debuggers\x86\gflags.exe /p /enable %PYTHON%\%EXECUTABLE%
- '%PYTHON%\%EXECUTABLE% -m pytest -vx --cov PIL --cov-report term --cov-report xml Tests'
- '%PYTHON%\%EXECUTABLE% -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests'
#- '%PYTHON%\%EXECUTABLE% test-installed.py -v -s %TEST_OPTIONS%' TODO TEST_OPTIONS with pytest?
after_test:

View File

@ -9,3 +9,10 @@ codecov:
token: 6dafc396-e7f5-4221-a38a-8b07a49fbdae
comment: off
# Matches 'omit:' in .coveragerc
ignore:
- "Tests/32bit_segfault_check.py"
- "Tests/bench_cffi_access.py"
- "Tests/check_*.py"
- "Tests/createfontdatachunk.py"

View File

@ -12,3 +12,10 @@ exclude_lines =
# Don't complain about debug code
if Image.DEBUG:
if DEBUG:
[run]
omit =
Tests/32bit_segfault_check.py
Tests/bench_cffi_access.py
Tests/check_*.py
Tests/createfontdatachunk.py

View File

@ -9,14 +9,14 @@ Please send a pull request to the master branch. Please include [documentation](
- Fork the Pillow repository.
- Create a branch from master.
- Develop bug fixes, features, tests, etc.
- Run the test suite on Python 2.7 and 3.x. You can enable [Travis CI](https://travis-ci.org/profile/) and [AppVeyor](https://ci.appveyor.com/projects/new) on your repo to catch test failures prior to the pull request, and [Codecov](https://codecov.io/gh) to see if the changed code is covered by tests.
- Run the test suite. You can enable [Travis CI](https://travis-ci.org/profile/) and [AppVeyor](https://ci.appveyor.com/projects/new) on your repo to catch test failures prior to the pull request, and [Codecov](https://codecov.io/gh) to see if the changed code is covered by tests.
- Create a pull request to pull the changes from your branch to the Pillow master.
### Guidelines
- Separate code commits from reformatting commits.
- Provide tests for any newly added code.
- Follow PEP8.
- Follow PEP 8.
- When committing only documentation changes please include [ci skip] in the commit message to avoid running tests on Travis-CI and AppVeyor.
## Reporting Issues

View File

@ -9,7 +9,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.5", "3.6", "3.7"]
python-version: ["3.5", "3.6", "3.7", "3.8", "pypy3.6"]
architecture: ["x86", "x64"]
include:
- architecture: "x86"
@ -31,6 +31,21 @@ jobs:
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v1
with:
repository: python-pillow/pillow-depends
ref: master
- name: Cache
uses: actions/cache@v1
with:
path: ~\AppData\Local\pip\Cache
key:
${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.architecture }}-${{ hashFiles('**/.github/workflows/test-windows.yml') }}
restore-keys: |
${{ runner.os }}-${{ matrix.python-version }}-${{ matrix.architecture }}-
${{ runner.os }}-${{ matrix.python-version }}-
- name: Install PyPy
if: "contains(matrix.python-version, 'pypy')"
run: |
@ -55,32 +70,25 @@ jobs:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.architecture }}
- name: pip install wheel pytest pytest-cov codecov
- name: pip install wheel pytest pytest-cov
run: |
"%pythonLocation%\python.exe" -m pip install wheel pytest pytest-cov
pip install codecov
shell: cmd
- name: Fetch dependencies
run: |
curl -fsSL -o nasm.zip https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/win64/nasm-2.14.02-win64.zip
7z x nasm.zip "-o$env:RUNNER_WORKSPACE\"
7z x ..\pillow-depends\nasm-2.14.02-win64.zip "-o$env:RUNNER_WORKSPACE\"
Write-Host "`#`#[add-path]$env:RUNNER_WORKSPACE\nasm-2.14.02"
Write-Host "::add-path::$env:RUNNER_WORKSPACE\nasm-2.14.02"
# 32-bit should work on both platforms
curl -fsSL -o gs950.exe https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs950/gs950w32.exe
./gs950.exe /S
..\pillow-depends\gs950w32.exe /S
Write-Host "`#`#[add-path]C:\Program Files (x86)\gs\gs9.50\bin"
Write-Host "::add-path::C:\Program Files (x86)\gs\gs9.50\bin"
$env:PYTHON=$env:pythonLocation
curl -fsSL -o pillow-depends.zip https://github.com/python-pillow/pillow-depends/archive/master.zip
7z x pillow-depends.zip -oc:\
mv c:\pillow-depends-master c:\pillow-depends
xcopy c:\pillow-depends\*.zip $env:GITHUB_WORKSPACE\winbuild\
xcopy c:\pillow-depends\*.tar.gz $env:GITHUB_WORKSPACE\winbuild\
xcopy /s c:\pillow-depends\test_images\* $env:GITHUB_WORKSPACE\tests\images\
xcopy ..\pillow-depends\*.zip $env:GITHUB_WORKSPACE\winbuild\
xcopy ..\pillow-depends\*.tar.gz $env:GITHUB_WORKSPACE\winbuild\
xcopy /s ..\pillow-depends\test_images\* $env:GITHUB_WORKSPACE\tests\images\
cd $env:GITHUB_WORKSPACE/winbuild/
python.exe $env:GITHUB_WORKSPACE\winbuild\build_dep.py
env:
@ -253,7 +261,6 @@ jobs:
# for Raqm
- name: Build dependencies / HarfBuzz
if: "!contains(matrix.python-version, 'pypy')"
run: |
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
@ -274,7 +281,6 @@ jobs:
# for Raqm
- name: Build dependencies / FriBidi
if: "!contains(matrix.python-version, 'pypy')"
run: |
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
@ -292,9 +298,7 @@ jobs:
copy /Y /B *.lib %INCLIB%
shell: cmd
# failing with PyPy3
- name: Build dependencies / Raqm
if: "!contains(matrix.python-version, 'pypy')"
run: |
set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\V7.1A\Include
set INCLIB=%GITHUB_WORKSPACE%\winbuild\depends\msvcr10-x32
@ -324,6 +328,7 @@ jobs:
set LIB=%INCLIB%;%PYTHON%\tcl
set INCLUDE=%INCLIB%;%GITHUB_WORKSPACE%\depends\tcl86\include;%INCLUDE%
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.platform-vcvars }}
set MSSdk=1
set DISTUTILS_USE_SDK=1
set py_vcruntime_redist=true
%PYTHON%\python.exe setup.py build_ext install
@ -346,7 +351,7 @@ jobs:
rem Add libraqm.dll (copied to INCLIB) to PATH.
path %INCLIB%;%PATH%
cd /D %GITHUB_WORKSPACE%
%PYTHON%\python.exe -m pytest -vx --cov PIL --cov-report term --cov-report xml Tests
%PYTHON%\python.exe -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests
shell: cmd
- name: Upload errors
@ -357,8 +362,11 @@ jobs:
path: Tests/errors
- name: Upload coverage
run: 'codecov --file "%GITHUB_WORKSPACE%\coverage.xml" --name "%pythonLocation%"'
shell: cmd
if: success()
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
name: ${{ runner.os }} Python ${{ matrix.python-version }}
- name: Build wheel
id: wheel

View File

@ -30,6 +30,26 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: Ubuntu cache
uses: actions/cache@v1
if: startsWith(matrix.os, 'ubuntu')
with:
path: ~/.cache/pip
key:
${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('**/.travis/*.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('**/.travis/*.sh') }}
restore-keys: |
${{ matrix.os }}-${{ matrix.python-version }}-
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
@ -71,5 +91,13 @@ jobs:
run: |
.travis/after_success.sh
env:
MATRIX_OS: ${{ matrix.os }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
- name: Upload coverage
if: success()
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
name: ${{ matrix.os }} Python ${{ matrix.python-version }}

View File

@ -6,8 +6,8 @@ notifications:
irc: "chat.freenode.net#pil"
# Run fast lint first to get fast feedback.
# Run slow PyPy* next, to give them a headstart and reduce waiting time.
# Run latest 3.x and 2.x next, to get quick compatibility results.
# Run slow PyPy next, to give it a headstart and reduce waiting time.
# Run latest 3.x next, to get quick compatibility results.
# Then run the remainder, with fastest Docker jobs last.
matrix:

View File

@ -1,7 +1,12 @@
#!/bin/bash
# gather the coverage data
sudo apt-get -qq install lcov
if [[ "$MATRIX_OS" == "macOS-latest" ]]; then
brew install lcov
else
sudo apt-get -qq install lcov
fi
lcov --capture --directory . -b . --output-file coverage.info
# filter to remove system headers
lcov --remove coverage.info '/usr/*' -o coverage.filtered.info
@ -11,16 +16,14 @@ coveralls-lcov -v -n coverage.filtered.info > coverage.c.json
coverage report
pip install codecov
if [[ $TRAVIS_PYTHON_VERSION != "2.7_with_system_site_packages" ]]; then
# Not working here. Just skip it, it's being removed soon.
pip install coveralls-merge
coveralls-merge coverage.c.json
pip install coveralls-merge
coveralls-merge coverage.c.json
if [[ $TRAVIS ]]; then
codecov
fi
codecov
if [ "$TRAVIS_PYTHON_VERSION" == "2.7" ] && [ "$DOCKER" == "" ]; then
if [ "$TRAVIS_PYTHON_VERSION" == "3.7" ] && [ "$DOCKER" == "" ]; then
# Coverage and quality reports on just the latest diff.
# (Installation is very slow on Py3, so just do it for Py2.)
depends/diffcover-install.sh
depends/diffcover-run.sh
fi

View File

@ -20,8 +20,8 @@ if [[ $TRAVIS_PYTHON_VERSION == 3.* ]]; then
pip install pyqt5
fi
# docs only on Python 2.7
if [ "$TRAVIS_PYTHON_VERSION" == "2.7" ]; then pip install -r requirements.txt ; fi
# docs only on Python 3.7
if [ "$TRAVIS_PYTHON_VERSION" == "3.7" ]; then pip install -r requirements.txt ; fi
# webp
pushd depends && ./install_webp.sh && popd

View File

@ -2,7 +2,7 @@
set -e
python -m pytest -v -x --cov PIL --cov-report term Tests
python -m pytest -v -x --cov PIL --cov Tests --cov-report term Tests
# Docs
if [ "$TRAVIS_PYTHON_VERSION" == "2.7" ]; then make doccheck; fi
if [ "$TRAVIS_PYTHON_VERSION" == "3.7" ]; then make doccheck; fi

View File

@ -5,6 +5,24 @@ Changelog (Pillow)
7.0.0 (unreleased)
------------------
- Handle broken Photoshop data #4239
[radarhere]
- Raise a specific exception if no data is found for an MPO frame #4240
[radarhere]
- Fix Unicode support for PyPy #4145
[nulano]
- Drop support for EOL Python 2.7 #4109
[hugovk, radarhere, jdufresne]
- Added UnidentifiedImageError #4182
[radarhere, hugovk]
- Remove deprecated __version__ from plugins #4197
[hugovk, radarhere]
- Fixed freeing unallocated pointer when resizing with height too large #4116
[radarhere]
@ -14,7 +32,7 @@ Changelog (Pillow)
- Corrected DdsImagePlugin setting info gamma #4171
[radarhere]
- Depends: Update libtiff to 4.1.0 #4195
- Depends: Update libtiff to 4.1.0 #4195, Tk Tcl to 8.6.10 #4229
[radarhere]
- Improve handling of file resources #3577

View File

@ -3,7 +3,7 @@
.DEFAULT_GOAL := release-test
clean:
python setup.py clean
python3 setup.py clean
rm src/PIL/*.so || true
rm -r build || true
find . -name __pycache__ | xargs rm -r || true
@ -15,8 +15,8 @@ co:
done
coverage:
python selftest.py
python setup.py test
python3 selftest.py
python3 setup.py test
rm -r htmlcov || true
coverage report
@ -30,7 +30,7 @@ doccheck:
$(MAKE) -C docs linkcheck || true
docserve:
cd docs/_build/html && python -mSimpleHTTPServer 2> /dev/null&
cd docs/_build/html && python3 -mSimpleHTTPServer 2> /dev/null&
help:
@echo "Welcome to Pillow development. Please use \`make <target>\` where <target> is one of"
@ -50,22 +50,22 @@ help:
@echo " upload-test build and upload sdists to test.pythonpackages.com"
inplace: clean
python setup.py develop build_ext --inplace
python3 setup.py develop build_ext --inplace
install:
python setup.py install
python selftest.py
python3 setup.py install
python3 selftest.py
install-coverage:
CFLAGS="-coverage" python setup.py build_ext install
python selftest.py
CFLAGS="-coverage" python3 setup.py build_ext install
python3 selftest.py
debug:
# make a debug version if we don't have a -dbg python. Leaves in symbols
# for our stuff, kills optimization, and redirects to dev null so we
# see any build failures.
make clean > /dev/null
CFLAGS='-g -O0' python setup.py build_ext install > /dev/null
CFLAGS='-g -O0' python3 setup.py build_ext install > /dev/null
install-req:
pip install -r requirements.txt
@ -76,17 +76,17 @@ install-venv:
release-test:
$(MAKE) install-req
python setup.py develop
python selftest.py
python -m pytest Tests
python setup.py install
python -m pytest -qq
python3 setup.py develop
python3 selftest.py
python3 -m pytest Tests
python3 setup.py install
python3 -m pytest -qq
check-manifest
pyroma .
viewdoc
sdist:
python setup.py sdist --format=gztar
python3 setup.py sdist --format=gztar
test:
pytest -qq
@ -97,10 +97,10 @@ upload-test:
# username:
# password:
# repository = http://test.pythonpackages.com
python setup.py sdist --format=gztar upload -r test
python3 setup.py sdist --format=gztar upload -r test
upload:
python setup.py sdist --format=gztar upload
python3 setup.py sdist --format=gztar upload
readme:
viewdoc

View File

@ -27,6 +27,6 @@ Run all the tests from the root of the Pillow source distribution::
Or with coverage::
pytest --cov PIL --cov-report term
pytest --cov PIL --cov Tests --cov-report term
coverage html
open htmlcov/index.html

View File

@ -1,8 +1,9 @@
import time
import unittest
from PIL import PyAccess
from .helper import PillowTestCase, hopper, unittest
from .helper import PillowTestCase, hopper
# Not running this test by default. No DOS against Travis CI.

View File

@ -1,23 +0,0 @@
import sys
import timeit
from . import helper
sys.path.insert(0, ".")
def bench(mode):
im = helper.hopper(mode)
get = im.im.getpixel
xy = 50, 50 # position shouldn't really matter
t0 = timeit.default_timer()
for _ in range(1000000):
get(xy)
print(mode, timeit.default_timer() - t0, "us")
bench("L")
bench("I")
bench("I;16")
bench("F")
bench("RGB")

View File

@ -1,6 +1,8 @@
import unittest
from PIL import Image
from .helper import PillowTestCase, unittest
from .helper import PillowTestCase
TEST_FILE = "Tests/images/fli_overflow.fli"
@ -9,8 +11,8 @@ class TestFliOverflow(PillowTestCase):
def test_fli_overflow(self):
# this should not crash with a malloc error or access violation
im = Image.open(TEST_FILE)
im.load()
with Image.open(TEST_FILE) as im:
im.load()
if __name__ == "__main__":

View File

@ -1,10 +1,9 @@
#!/usr/bin/env python
from __future__ import division
import unittest
from PIL import Image
from .helper import PillowTestCase, is_win32, unittest
from .helper import PillowTestCase, is_win32
min_iterations = 100
max_iterations = 10000

View File

@ -1,8 +1,9 @@
import unittest
from io import BytesIO
from PIL import Image
from .helper import PillowTestCase, is_win32, unittest
from .helper import PillowTestCase, is_win32
# Limits for testing the leak
mem_limit = 1024 * 1048576

View File

@ -1,6 +1,8 @@
import unittest
from PIL import Image
from .helper import PillowTestCase, unittest
from .helper import PillowTestCase
class TestJ2kEncodeOverflow(PillowTestCase):

View File

@ -1,6 +1,7 @@
import unittest
from io import BytesIO
from .helper import PillowTestCase, hopper, is_win32, unittest
from .helper import PillowTestCase, hopper, is_win32
iterations = 5000

View File

@ -1,8 +1,9 @@
import sys
import unittest
from PIL import Image
from .helper import PillowTestCase, unittest
from .helper import PillowTestCase
# This test is not run automatically.
#

View File

@ -1,8 +1,9 @@
import sys
import unittest
from PIL import Image
from .helper import PillowTestCase, unittest
from .helper import PillowTestCase
# This test is not run automatically.
#

View File

@ -1,6 +1,8 @@
import unittest
from PIL import Image
from .helper import PillowTestCase, unittest
from .helper import PillowTestCase
TEST_FILE = "Tests/images/libtiff_segfault.tif"
@ -12,8 +14,8 @@ class TestLibtiffSegfault(PillowTestCase):
"""
with self.assertRaises(IOError):
im = Image.open(TEST_FILE)
im.load()
with Image.open(TEST_FILE) as im:
im.load()
if __name__ == "__main__":

View File

@ -1,9 +1,10 @@
import unittest
import zlib
from io import BytesIO
from PIL import Image, ImageFile, PngImagePlugin
from .helper import PillowTestCase, unittest
from .helper import PillowTestCase
TEST_FILE = "Tests/images/png_decompression_dos.png"

View File

@ -1,6 +1,4 @@
#!/usr/bin/env python
from __future__ import print_function
import base64
import os

View File

@ -1,7 +1,6 @@
"""
Helper functions.
"""
from __future__ import print_function
import logging
import os
@ -12,7 +11,6 @@ import unittest
from io import BytesIO
from PIL import Image, ImageMath
from PIL._util import py3
logger = logging.getLogger(__name__)
@ -76,10 +74,13 @@ class PillowTestCase(unittest.TestCase):
def assert_deep_equal(self, a, b, msg=None):
try:
self.assertEqual(
len(a), len(b), msg or "got length %s, expected %s" % (len(a), len(b))
len(a),
len(b),
msg or "got length {}, expected {}".format(len(a), len(b)),
)
self.assertTrue(
all(x == y for x, y in zip(a, b)), msg or "got %s, expected %s" % (a, b)
all(x == y for x, y in zip(a, b)),
msg or "got {}, expected {}".format(a, b),
)
except Exception:
self.assertEqual(a, b, msg)
@ -87,20 +88,24 @@ class PillowTestCase(unittest.TestCase):
def assert_image(self, im, mode, size, msg=None):
if mode is not None:
self.assertEqual(
im.mode, mode, msg or "got mode %r, expected %r" % (im.mode, mode)
im.mode,
mode,
msg or "got mode {!r}, expected {!r}".format(im.mode, mode),
)
if size is not None:
self.assertEqual(
im.size, size, msg or "got size %r, expected %r" % (im.size, size)
im.size,
size,
msg or "got size {!r}, expected {!r}".format(im.size, size),
)
def assert_image_equal(self, a, b, msg=None):
self.assertEqual(
a.mode, b.mode, msg or "got mode %r, expected %r" % (a.mode, b.mode)
a.mode, b.mode, msg or "got mode {!r}, expected {!r}".format(a.mode, b.mode)
)
self.assertEqual(
a.size, b.size, msg or "got size %r, expected %r" % (a.size, b.size)
a.size, b.size, msg or "got size {!r}, expected {!r}".format(a.size, b.size)
)
if a.tobytes() != b.tobytes():
if HAS_UPLOADER:
@ -121,10 +126,10 @@ class PillowTestCase(unittest.TestCase):
def assert_image_similar(self, a, b, epsilon, msg=None):
epsilon = float(epsilon)
self.assertEqual(
a.mode, b.mode, msg or "got mode %r, expected %r" % (a.mode, b.mode)
a.mode, b.mode, msg or "got mode {!r}, expected {!r}".format(a.mode, b.mode)
)
self.assertEqual(
a.size, b.size, msg or "got size %r, expected %r" % (a.size, b.size)
a.size, b.size, msg or "got size {!r}, expected {!r}".format(a.size, b.size)
)
a, b = convert_to_comparable(a, b)
@ -216,12 +221,12 @@ class PillowTestCase(unittest.TestCase):
def open_withImagemagick(self, f):
if not imagemagick_available():
raise IOError()
raise OSError()
outfile = self.tempfile("temp.png")
if command_succeeds([IMCONVERT, f, outfile]):
return Image.open(outfile)
raise IOError()
raise OSError()
@unittest.skipIf(sys.platform.startswith("win32"), "requires Unix or macOS")
@ -264,11 +269,6 @@ class PillowLeakTestCase(PillowTestCase):
# helpers
if not py3:
# Remove DeprecationWarning in Python 3
PillowTestCase.assertRaisesRegex = PillowTestCase.assertRaisesRegexp
PillowTestCase.assertRegex = PillowTestCase.assertRegexpMatches
def fromstring(data):
return Image.open(BytesIO(data))
@ -306,11 +306,10 @@ def command_succeeds(cmd):
Runs the command, which must be a list of strings. Returns True if the
command succeeds, or False if an OSError was raised by subprocess.Popen.
"""
with open(os.devnull, "wb") as f:
try:
subprocess.call(cmd, stdout=f, stderr=subprocess.STDOUT)
except OSError:
return False
try:
subprocess.call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
except OSError:
return False
return True
@ -373,7 +372,7 @@ def distro():
return line.strip().split("=")[1]
class cached_property(object):
class cached_property:
def __init__(self, func):
self.func = func

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

View File

@ -1,16 +0,0 @@
from __future__ import print_function
import glob
import os
import sys
import traceback
sys.path.insert(0, ".")
for file in glob.glob("src/PIL/*.py"):
module = os.path.basename(file)[:-3]
try:
exec("from PIL import " + module)
except (ImportError, SyntaxError):
print("===", "failed to import", module)
traceback.print_exc()

View File

@ -1,68 +0,0 @@
# brute-force search for access descriptor hash table
from __future__ import print_function
modes = [
"1",
"L",
"LA",
"La",
"I",
"I;16",
"I;16L",
"I;16B",
"I;32L",
"I;32B",
"F",
"P",
"PA",
"RGB",
"RGBA",
"RGBa",
"RGBX",
"CMYK",
"YCbCr",
"LAB",
"HSV",
]
def hash(s, i):
# djb2 hash: multiply by 33 and xor character
for c in s:
i = (((i << 5) + i) ^ ord(c)) & 0xFFFFFFFF
return i
def check(size, i0):
h = [None] * size
for m in modes:
i = hash(m, i0)
i = i % size
if h[i]:
return 0
h[i] = m
return h
min_start = 0
# 1) find the smallest table size with no collisions
for min_size in range(len(modes), 16384):
if check(min_size, 0):
print(len(modes), "modes fit in", min_size, "slots")
break
# 2) see if we can do better with a different initial value
for i0 in range(65556):
for size in range(1, min_size):
if check(size, i0):
if size < min_size:
print(len(modes), "modes fit in", size, "slots with start", i0)
min_size = size
min_start = i0
print()
print("#define ACCESS_TABLE_SIZE", min_size)
print("#define ACCESS_TABLE_HASH", min_start)

View File

@ -1,5 +1,3 @@
from __future__ import print_function
import os
from PIL import Image
@ -109,4 +107,4 @@ class TestBmpReference(PillowTestCase):
os.path.join(base, "g", "pal4rle.bmp"),
)
if f not in unsupported:
self.fail("Unsupported Image %s: %s" % (f, msg))
self.fail("Unsupported Image {}: {}".format(f, msg))

View File

@ -1,10 +1,9 @@
from __future__ import division
import unittest
from array import array
from PIL import Image, ImageFilter
from .helper import PillowTestCase, unittest
from .helper import PillowTestCase
try:
import numpy

View File

@ -1,10 +1,9 @@
from __future__ import division, print_function
import sys
import unittest
from PIL import Image
from .helper import PillowTestCase, is_pypy, unittest
from .helper import PillowTestCase, is_pypy
class TestCoreStats(PillowTestCase):

View File

@ -1,10 +1,9 @@
from __future__ import unicode_literals
import io
import unittest
from PIL import features
from .helper import PillowTestCase, unittest
from .helper import PillowTestCase
try:
from PIL import _webp

View File

@ -15,6 +15,6 @@ class TestFileBlp(PillowTestCase):
self.assert_image_equal(im, target)
def test_load_blp2_dxt1a(self):
im = Image.open("Tests/images/blp/blp2_dxt1a.blp")
target = Image.open("Tests/images/blp/blp2_dxt1a.png")
self.assert_image_equal(im, target)
with Image.open("Tests/images/blp/blp2_dxt1a.blp") as im:
with Image.open("Tests/images/blp/blp2_dxt1a.png") as target:
self.assert_image_equal(im, target)

View File

@ -11,12 +11,12 @@ class TestFileBmp(PillowTestCase):
im.save(outfile, "BMP")
reloaded = Image.open(outfile)
reloaded.load()
self.assertEqual(im.mode, reloaded.mode)
self.assertEqual(im.size, reloaded.size)
self.assertEqual(reloaded.format, "BMP")
self.assertEqual(reloaded.get_format_mimetype(), "image/bmp")
with Image.open(outfile) as reloaded:
reloaded.load()
self.assertEqual(im.mode, reloaded.mode)
self.assertEqual(im.size, reloaded.size)
self.assertEqual(reloaded.format, "BMP")
self.assertEqual(reloaded.get_format_mimetype(), "image/bmp")
def test_sanity(self):
self.roundtrip(hopper())
@ -36,11 +36,10 @@ class TestFileBmp(PillowTestCase):
im.save(output, "BMP")
output.seek(0)
reloaded = Image.open(output)
self.assertEqual(im.mode, reloaded.mode)
self.assertEqual(im.size, reloaded.size)
self.assertEqual(reloaded.format, "BMP")
with Image.open(output) as reloaded:
self.assertEqual(im.mode, reloaded.mode)
self.assertEqual(im.size, reloaded.size)
self.assertEqual(reloaded.format, "BMP")
def test_dpi(self):
dpi = (72, 72)
@ -57,17 +56,17 @@ class TestFileBmp(PillowTestCase):
# Test for #1301
# Arrange
outfile = self.tempfile("temp.jpg")
im = Image.open("Tests/images/hopper.bmp")
with Image.open("Tests/images/hopper.bmp") as im:
# Act
im.save(outfile, "JPEG", dpi=im.info["dpi"])
# Act
im.save(outfile, "JPEG", dpi=im.info["dpi"])
# Assert
reloaded = Image.open(outfile)
reloaded.load()
self.assertEqual(im.info["dpi"], reloaded.info["dpi"])
self.assertEqual(im.size, reloaded.size)
self.assertEqual(reloaded.format, "JPEG")
# Assert
with Image.open(outfile) as reloaded:
reloaded.load()
self.assertEqual(im.info["dpi"], reloaded.info["dpi"])
self.assertEqual(im.size, reloaded.size)
self.assertEqual(reloaded.format, "JPEG")
def test_load_dpi_rounding(self):
# Round up
@ -80,11 +79,10 @@ class TestFileBmp(PillowTestCase):
def test_save_dpi_rounding(self):
outfile = self.tempfile("temp.bmp")
im = Image.open("Tests/images/hopper.bmp")
im.save(outfile, dpi=(72.2, 72.2))
with Image.open(outfile) as reloaded:
self.assertEqual(reloaded.info["dpi"], (72, 72))
with Image.open("Tests/images/hopper.bmp") as im:
im.save(outfile, dpi=(72.2, 72.2))
with Image.open(outfile) as reloaded:
self.assertEqual(reloaded.info["dpi"], (72, 72))
im.save(outfile, dpi=(72.8, 72.8))
with Image.open(outfile) as reloaded:
@ -92,32 +90,32 @@ class TestFileBmp(PillowTestCase):
def test_load_dib(self):
# test for #1293, Imagegrab returning Unsupported Bitfields Format
im = Image.open("Tests/images/clipboard.dib")
self.assertEqual(im.format, "DIB")
self.assertEqual(im.get_format_mimetype(), "image/bmp")
with Image.open("Tests/images/clipboard.dib") as im:
self.assertEqual(im.format, "DIB")
self.assertEqual(im.get_format_mimetype(), "image/bmp")
target = Image.open("Tests/images/clipboard_target.png")
self.assert_image_equal(im, target)
with Image.open("Tests/images/clipboard_target.png") as target:
self.assert_image_equal(im, target)
def test_save_dib(self):
outfile = self.tempfile("temp.dib")
im = Image.open("Tests/images/clipboard.dib")
im.save(outfile)
with Image.open("Tests/images/clipboard.dib") as im:
im.save(outfile)
reloaded = Image.open(outfile)
self.assertEqual(reloaded.format, "DIB")
self.assertEqual(reloaded.get_format_mimetype(), "image/bmp")
self.assert_image_equal(im, reloaded)
with Image.open(outfile) as reloaded:
self.assertEqual(reloaded.format, "DIB")
self.assertEqual(reloaded.get_format_mimetype(), "image/bmp")
self.assert_image_equal(im, reloaded)
def test_rgba_bitfields(self):
# This test image has been manually hexedited
# to change the bitfield compression in the header from XBGR to RGBA
im = Image.open("Tests/images/rgb32bf-rgba.bmp")
with Image.open("Tests/images/rgb32bf-rgba.bmp") as im:
# So before the comparing the image, swap the channels
b, g, r = im.split()[1:]
im = Image.merge("RGB", (r, g, b))
# So before the comparing the image, swap the channels
b, g, r = im.split()[1:]
im = Image.merge("RGB", (r, g, b))
target = Image.open("Tests/images/bmp/q/rgb32bf-xbgr.bmp")
self.assert_image_equal(im, target)
with Image.open("Tests/images/bmp/q/rgb32bf-xbgr.bmp") as target:
self.assert_image_equal(im, target)

View File

@ -7,14 +7,13 @@ TEST_FILE = "Tests/images/deerstalker.cur"
class TestFileCur(PillowTestCase):
def test_sanity(self):
im = Image.open(TEST_FILE)
self.assertEqual(im.size, (32, 32))
self.assertIsInstance(im, CurImagePlugin.CurImageFile)
# Check some pixel colors to ensure image is loaded properly
self.assertEqual(im.getpixel((10, 1)), (0, 0, 0, 0))
self.assertEqual(im.getpixel((11, 1)), (253, 254, 254, 1))
self.assertEqual(im.getpixel((16, 16)), (84, 87, 86, 255))
with Image.open(TEST_FILE) as im:
self.assertEqual(im.size, (32, 32))
self.assertIsInstance(im, CurImagePlugin.CurImageFile)
# Check some pixel colors to ensure image is loaded properly
self.assertEqual(im.getpixel((10, 1)), (0, 0, 0, 0))
self.assertEqual(im.getpixel((11, 1)), (253, 254, 254, 1))
self.assertEqual(im.getpixel((16, 16)), (84, 87, 86, 255))
def test_invalid_file(self):
invalid_file = "Tests/images/flower.jpg"

View File

@ -17,73 +17,71 @@ class TestFileDds(PillowTestCase):
def test_sanity_dxt1(self):
"""Check DXT1 images can be opened"""
target = Image.open(TEST_FILE_DXT1.replace(".dds", ".png"))
with Image.open(TEST_FILE_DXT1.replace(".dds", ".png")) as target:
target = target.convert("RGBA")
with Image.open(TEST_FILE_DXT1) as im:
im.load()
im = Image.open(TEST_FILE_DXT1)
im.load()
self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (256, 256))
self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (256, 256))
self.assert_image_equal(target.convert("RGBA"), im)
self.assert_image_equal(im, target)
def test_sanity_dxt5(self):
"""Check DXT5 images can be opened"""
target = Image.open(TEST_FILE_DXT5.replace(".dds", ".png"))
im = Image.open(TEST_FILE_DXT5)
im.load()
with Image.open(TEST_FILE_DXT5) as im:
im.load()
self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (256, 256))
self.assert_image_equal(target, im)
with Image.open(TEST_FILE_DXT5.replace(".dds", ".png")) as target:
self.assert_image_equal(target, im)
def test_sanity_dxt3(self):
"""Check DXT3 images can be opened"""
target = Image.open(TEST_FILE_DXT3.replace(".dds", ".png"))
with Image.open(TEST_FILE_DXT3.replace(".dds", ".png")) as target:
with Image.open(TEST_FILE_DXT3) as im:
im.load()
im = Image.open(TEST_FILE_DXT3)
im.load()
self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (256, 256))
self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (256, 256))
self.assert_image_equal(target, im)
self.assert_image_equal(target, im)
def test_dx10_bc7(self):
"""Check DX10 images can be opened"""
target = Image.open(TEST_FILE_DX10_BC7.replace(".dds", ".png"))
with Image.open(TEST_FILE_DX10_BC7) as im:
im.load()
im = Image.open(TEST_FILE_DX10_BC7)
im.load()
self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (256, 256))
self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (256, 256))
self.assert_image_equal(target, im)
with Image.open(TEST_FILE_DX10_BC7.replace(".dds", ".png")) as target:
self.assert_image_equal(target, im)
def test_dx10_bc7_unorm_srgb(self):
"""Check DX10 unsigned normalized integer images can be opened"""
target = Image.open(TEST_FILE_DX10_BC7_UNORM_SRGB.replace(".dds", ".png"))
with Image.open(TEST_FILE_DX10_BC7_UNORM_SRGB) as im:
im.load()
im = Image.open(TEST_FILE_DX10_BC7_UNORM_SRGB)
im.load()
self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (16, 16))
self.assertEqual(im.info["gamma"], 1 / 2.2)
self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (16, 16))
self.assertEqual(im.info["gamma"], 1 / 2.2)
self.assert_image_equal(target, im)
with Image.open(
TEST_FILE_DX10_BC7_UNORM_SRGB.replace(".dds", ".png")
) as target:
self.assert_image_equal(target, im)
def test_unimplemented_dxgi_format(self):
self.assertRaises(
@ -95,16 +93,17 @@ class TestFileDds(PillowTestCase):
def test_uncompressed_rgb(self):
"""Check uncompressed RGB images can be opened"""
target = Image.open(TEST_FILE_UNCOMPRESSED_RGB.replace(".dds", ".png"))
with Image.open(TEST_FILE_UNCOMPRESSED_RGB) as im:
im.load()
im = Image.open(TEST_FILE_UNCOMPRESSED_RGB)
im.load()
self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (800, 600))
self.assertEqual(im.format, "DDS")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (800, 600))
self.assert_image_equal(target, im)
with Image.open(
TEST_FILE_UNCOMPRESSED_RGB.replace(".dds", ".png")
) as target:
self.assert_image_equal(target, im)
def test__validate_true(self):
"""Check valid prefix"""
@ -145,8 +144,8 @@ class TestFileDds(PillowTestCase):
img_file = f.read()
def short_file():
im = Image.open(BytesIO(img_file[:-100]))
im.load()
with Image.open(BytesIO(img_file[:-100])) as im:
im.load()
self.assertRaises(IOError, short_file)

View File

@ -1,8 +1,9 @@
import io
import unittest
from PIL import EpsImagePlugin, Image
from .helper import PillowTestCase, hopper, unittest
from .helper import PillowTestCase, hopper
HAS_GHOSTSCRIPT = EpsImagePlugin.has_ghostscript()
@ -67,8 +68,8 @@ class TestFileEps(PillowTestCase):
self.assertEqual(cmyk_image.mode, "RGB")
if "jpeg_decoder" in dir(Image.core):
target = Image.open("Tests/images/pil_sample_rgb.jpg")
self.assert_image_similar(cmyk_image, target, 10)
with Image.open("Tests/images/pil_sample_rgb.jpg") as target:
self.assert_image_similar(cmyk_image, target, 10)
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
def test_showpage(self):
@ -91,7 +92,7 @@ class TestFileEps(PillowTestCase):
def test_iobase_object(self):
# issue 479
with Image.open(file1) as image1:
with io.open(self.tempfile("temp_iobase.eps"), "wb") as fh:
with open(self.tempfile("temp_iobase.eps"), "wb") as fh:
image1.save(fh, "EPS")
@unittest.skipUnless(HAS_GHOSTSCRIPT, "Ghostscript not available")
@ -99,12 +100,13 @@ class TestFileEps(PillowTestCase):
with open(file1, "rb") as f:
img_bytes = io.BytesIO(f.read())
img = Image.open(img_bytes)
img.load()
with Image.open(img_bytes) as img:
img.load()
image1_scale1_compare = Image.open(file1_compare).convert("RGB")
image1_scale1_compare.load()
self.assert_image_similar(img, image1_scale1_compare, 5)
with Image.open(file1_compare) as image1_scale1_compare:
image1_scale1_compare = image1_scale1_compare.convert("RGB")
image1_scale1_compare.load()
self.assert_image_similar(img, image1_scale1_compare, 5)
def test_image_mode_not_supported(self):
im = hopper("RGBA")
@ -121,14 +123,16 @@ class TestFileEps(PillowTestCase):
# Zero bounding box
with Image.open(file1) as image1_scale1:
image1_scale1.load()
image1_scale1_compare = Image.open(file1_compare).convert("RGB")
with Image.open(file1_compare) as image1_scale1_compare:
image1_scale1_compare = image1_scale1_compare.convert("RGB")
image1_scale1_compare.load()
self.assert_image_similar(image1_scale1, image1_scale1_compare, 5)
# Non-Zero bounding box
with Image.open(file2) as image2_scale1:
image2_scale1.load()
image2_scale1_compare = Image.open(file2_compare).convert("RGB")
with Image.open(file2_compare) as image2_scale1_compare:
image2_scale1_compare = image2_scale1_compare.convert("RGB")
image2_scale1_compare.load()
self.assert_image_similar(image2_scale1, image2_scale1_compare, 10)
@ -142,14 +146,16 @@ class TestFileEps(PillowTestCase):
# Zero bounding box
with Image.open(file1) as image1_scale2:
image1_scale2.load(scale=2)
image1_scale2_compare = Image.open(file1_compare_scale2).convert("RGB")
with Image.open(file1_compare_scale2) as image1_scale2_compare:
image1_scale2_compare = image1_scale2_compare.convert("RGB")
image1_scale2_compare.load()
self.assert_image_similar(image1_scale2, image1_scale2_compare, 5)
# Non-Zero bounding box
with Image.open(file2) as image2_scale2:
image2_scale2.load(scale=2)
image2_scale2_compare = Image.open(file2_compare_scale2).convert("RGB")
with Image.open(file2_compare_scale2) as image2_scale2_compare:
image2_scale2_compare = image2_scale2_compare.convert("RGB")
image2_scale2_compare.load()
self.assert_image_similar(image2_scale2, image2_scale2_compare, 10)

View File

@ -1,4 +1,6 @@
from .helper import PillowTestCase, unittest
import unittest
from .helper import PillowTestCase
try:
from PIL import FpxImagePlugin

View File

@ -5,12 +5,11 @@ from .helper import PillowTestCase
class TestFileFtex(PillowTestCase):
def test_load_raw(self):
im = Image.open("Tests/images/ftex_uncompressed.ftu")
target = Image.open("Tests/images/ftex_uncompressed.png")
self.assert_image_equal(im, target)
with Image.open("Tests/images/ftex_uncompressed.ftu") as im:
with Image.open("Tests/images/ftex_uncompressed.png") as target:
self.assert_image_equal(im, target)
def test_load_dxt1(self):
im = Image.open("Tests/images/ftex_dxt1.ftc")
target = Image.open("Tests/images/ftex_dxt1.png")
self.assert_image_similar(im, target.convert("RGBA"), 15)
with Image.open("Tests/images/ftex_dxt1.ftc") as im:
with Image.open("Tests/images/ftex_dxt1.png") as target:
self.assert_image_similar(im, target.convert("RGBA"), 15)

View File

@ -1,4 +1,4 @@
from PIL import GdImageFile
from PIL import GdImageFile, UnidentifiedImageError
from .helper import PillowTestCase
@ -17,4 +17,4 @@ class TestFileGd(PillowTestCase):
def test_invalid_file(self):
invalid_file = "Tests/images/flower.jpg"
self.assertRaises(IOError, GdImageFile.open, invalid_file)
self.assertRaises(UnidentifiedImageError, GdImageFile.open, invalid_file)

View File

@ -1,8 +1,9 @@
import unittest
from io import BytesIO
from PIL import GifImagePlugin, Image, ImageDraw, ImagePalette
from .helper import PillowTestCase, hopper, is_pypy, netpbm_available, unittest
from .helper import PillowTestCase, hopper, is_pypy, netpbm_available
try:
from PIL import _webp
@ -87,21 +88,20 @@ class TestFileGif(PillowTestCase):
def check(colors, size, expected_palette_length):
# make an image with empty colors in the start of the palette range
im = Image.frombytes(
"P",
(colors, colors),
bytes(bytearray(range(256 - colors, 256)) * colors),
"P", (colors, colors), bytes(range(256 - colors, 256)) * colors
)
im = im.resize((size, size))
outfile = BytesIO()
im.save(outfile, "GIF")
outfile.seek(0)
reloaded = Image.open(outfile)
with Image.open(outfile) as reloaded:
# check palette length
palette_length = max(
i + 1 for i, v in enumerate(reloaded.histogram()) if v
)
self.assertEqual(expected_palette_length, palette_length)
# check palette length
palette_length = max(i + 1 for i, v in enumerate(reloaded.histogram()) if v)
self.assertEqual(expected_palette_length, palette_length)
self.assert_image_equal(im.convert("RGB"), reloaded.convert("RGB"))
self.assert_image_equal(im.convert("RGB"), reloaded.convert("RGB"))
# These do optimize the palette
check(128, 511, 128)
@ -119,7 +119,7 @@ class TestFileGif(PillowTestCase):
check(256, 511, 256)
def test_optimize_full_l(self):
im = Image.frombytes("L", (16, 16), bytes(bytearray(range(256))))
im = Image.frombytes("L", (16, 16), bytes(range(256)))
test_file = BytesIO()
im.save(test_file, "GIF", optimize=True)
self.assertEqual(im.mode, "L")
@ -555,9 +555,9 @@ class TestFileGif(PillowTestCase):
self.assertEqual(reread.info["background"], im.info["background"])
if HAVE_WEBP and _webp.HAVE_WEBPANIM:
im = Image.open("Tests/images/hopper.webp")
self.assertIsInstance(im.info["background"], tuple)
im.save(out)
with Image.open("Tests/images/hopper.webp") as im:
self.assertIsInstance(im.info["background"], tuple)
im.save(out)
def test_comment(self):
with Image.open(TEST_GIF) as im:
@ -632,8 +632,7 @@ class TestFileGif(PillowTestCase):
# Tests appending using a generator
def imGenerator(ims):
for im in ims:
yield im
yield from ims
im.save(out, save_all=True, append_images=imGenerator(ims))
@ -655,7 +654,7 @@ class TestFileGif(PillowTestCase):
# that's > 128 items where the transparent color is actually
# the top palette entry to trigger the bug.
data = bytes(bytearray(range(1, 254)))
data = bytes(range(1, 254))
palette = ImagePalette.ImagePalette("RGB", list(range(256)) * 3)
im = Image.new("L", (253, 1))
@ -703,7 +702,7 @@ class TestFileGif(PillowTestCase):
im = hopper("P")
im_l = Image.frombytes("L", im.size, im.tobytes())
palette = bytes(bytearray(im.getpalette()))
palette = bytes(im.getpalette())
out = self.tempfile("temp.gif")
im_l.save(out, palette=palette)
@ -718,7 +717,7 @@ class TestFileGif(PillowTestCase):
# Forcing a non-straight grayscale palette.
im = hopper("P")
palette = bytes(bytearray([255 - i // 3 for i in range(768)]))
palette = bytes([255 - i // 3 for i in range(768)])
out = self.tempfile("temp.gif")
im.save(out, palette=palette)
@ -759,7 +758,7 @@ class TestFileGif(PillowTestCase):
im.putpalette(ImagePalette.ImagePalette("RGB"))
im.info = {"background": 0}
passed_palette = bytes(bytearray([255 - i // 3 for i in range(768)]))
passed_palette = bytes([255 - i // 3 for i in range(768)])
GifImagePlugin._FORCE_OPTIMIZE = True
try:

View File

@ -1,9 +1,10 @@
import io
import sys
import unittest
from PIL import IcnsImagePlugin, Image
from .helper import PillowTestCase, unittest
from .helper import PillowTestCase
# sample icon file
TEST_FILE = "Tests/images/pillow.icns"
@ -26,32 +27,31 @@ class TestFileIcns(PillowTestCase):
@unittest.skipIf(sys.platform != "darwin", "requires macOS")
def test_save(self):
im = Image.open(TEST_FILE)
temp_file = self.tempfile("temp.icns")
im.save(temp_file)
reread = Image.open(temp_file)
with Image.open(TEST_FILE) as im:
im.save(temp_file)
self.assertEqual(reread.mode, "RGBA")
self.assertEqual(reread.size, (1024, 1024))
self.assertEqual(reread.format, "ICNS")
with Image.open(temp_file) as reread:
self.assertEqual(reread.mode, "RGBA")
self.assertEqual(reread.size, (1024, 1024))
self.assertEqual(reread.format, "ICNS")
@unittest.skipIf(sys.platform != "darwin", "requires macOS")
def test_save_append_images(self):
im = Image.open(TEST_FILE)
temp_file = self.tempfile("temp.icns")
provided_im = Image.new("RGBA", (32, 32), (255, 0, 0, 128))
im.save(temp_file, append_images=[provided_im])
reread = Image.open(temp_file)
self.assert_image_similar(reread, im, 1)
with Image.open(TEST_FILE) as im:
im.save(temp_file, append_images=[provided_im])
reread = Image.open(temp_file)
reread.size = (16, 16, 2)
reread.load()
self.assert_image_equal(reread, provided_im)
with Image.open(temp_file) as reread:
self.assert_image_similar(reread, im, 1)
with Image.open(temp_file) as reread:
reread.size = (16, 16, 2)
reread.load()
self.assert_image_equal(reread, provided_im)
def test_sizes(self):
# Check that we can load all of the sizes, and that the final pixel

View File

@ -27,23 +27,23 @@ class TestFileIco(PillowTestCase):
# the default image
output.seek(0)
reloaded = Image.open(output)
self.assertEqual(reloaded.info["sizes"], {(32, 32), (64, 64)})
with Image.open(output) as reloaded:
self.assertEqual(reloaded.info["sizes"], {(32, 32), (64, 64)})
self.assertEqual(im.mode, reloaded.mode)
self.assertEqual((64, 64), reloaded.size)
self.assertEqual(reloaded.format, "ICO")
self.assert_image_equal(reloaded, hopper().resize((64, 64), Image.LANCZOS))
self.assertEqual(im.mode, reloaded.mode)
self.assertEqual((64, 64), reloaded.size)
self.assertEqual(reloaded.format, "ICO")
self.assert_image_equal(reloaded, hopper().resize((64, 64), Image.LANCZOS))
# the other one
output.seek(0)
reloaded = Image.open(output)
reloaded.size = (32, 32)
with Image.open(output) as reloaded:
reloaded.size = (32, 32)
self.assertEqual(im.mode, reloaded.mode)
self.assertEqual((32, 32), reloaded.size)
self.assertEqual(reloaded.format, "ICO")
self.assert_image_equal(reloaded, hopper().resize((32, 32), Image.LANCZOS))
self.assertEqual(im.mode, reloaded.mode)
self.assertEqual((32, 32), reloaded.size)
self.assertEqual(reloaded.format, "ICO")
self.assert_image_equal(reloaded, hopper().resize((32, 32), Image.LANCZOS))
def test_incorrect_size(self):
with Image.open(TEST_ICO_FILE) as im:

View File

@ -1,3 +1,6 @@
import sys
from io import StringIO
from PIL import Image, IptcImagePlugin
from .helper import PillowTestCase, hopper
@ -52,12 +55,6 @@ class TestFileIptc(PillowTestCase):
# Arrange
c = b"abc"
# Temporarily redirect stdout
try:
from cStringIO import StringIO
except ImportError:
from io import StringIO
import sys
old_stdout = sys.stdout
sys.stdout = mystdout = StringIO()

View File

@ -44,12 +44,12 @@ class TestFileJpeg(PillowTestCase):
# internal version number
self.assertRegex(Image.core.jpeglib_version, r"\d+\.\d+$")
im = Image.open(TEST_FILE)
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "JPEG")
self.assertEqual(im.get_format_mimetype(), "image/jpeg")
with Image.open(TEST_FILE) as im:
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "JPEG")
self.assertEqual(im.get_format_mimetype(), "image/jpeg")
def test_app(self):
# Test APP/COM reader (@PIL135)
@ -66,30 +66,34 @@ class TestFileJpeg(PillowTestCase):
# Test CMYK handling. Thanks to Tim and Charlie for test data,
# Michael for getting me to look one more time.
f = "Tests/images/pil_sample_cmyk.jpg"
im = Image.open(f)
# the source image has red pixels in the upper left corner.
c, m, y, k = [x / 255.0 for x in im.getpixel((0, 0))]
self.assertEqual(c, 0.0)
self.assertGreater(m, 0.8)
self.assertGreater(y, 0.8)
self.assertEqual(k, 0.0)
# the opposite corner is black
c, m, y, k = [x / 255.0 for x in im.getpixel((im.size[0] - 1, im.size[1] - 1))]
self.assertGreater(k, 0.9)
# roundtrip, and check again
im = self.roundtrip(im)
c, m, y, k = [x / 255.0 for x in im.getpixel((0, 0))]
self.assertEqual(c, 0.0)
self.assertGreater(m, 0.8)
self.assertGreater(y, 0.8)
self.assertEqual(k, 0.0)
c, m, y, k = [x / 255.0 for x in im.getpixel((im.size[0] - 1, im.size[1] - 1))]
self.assertGreater(k, 0.9)
with Image.open(f) as im:
# the source image has red pixels in the upper left corner.
c, m, y, k = [x / 255.0 for x in im.getpixel((0, 0))]
self.assertEqual(c, 0.0)
self.assertGreater(m, 0.8)
self.assertGreater(y, 0.8)
self.assertEqual(k, 0.0)
# the opposite corner is black
c, m, y, k = [
x / 255.0 for x in im.getpixel((im.size[0] - 1, im.size[1] - 1))
]
self.assertGreater(k, 0.9)
# roundtrip, and check again
im = self.roundtrip(im)
c, m, y, k = [x / 255.0 for x in im.getpixel((0, 0))]
self.assertEqual(c, 0.0)
self.assertGreater(m, 0.8)
self.assertGreater(y, 0.8)
self.assertEqual(k, 0.0)
c, m, y, k = [
x / 255.0 for x in im.getpixel((im.size[0] - 1, im.size[1] - 1))
]
self.assertGreater(k, 0.9)
def test_dpi(self):
def test(xdpi, ydpi=None):
im = Image.open(TEST_FILE)
im = self.roundtrip(im, dpi=(xdpi, ydpi or xdpi))
with Image.open(TEST_FILE) as im:
im = self.roundtrip(im, dpi=(xdpi, ydpi or xdpi))
return im.info.get("dpi")
self.assertEqual(test(72), (72, 72))
@ -140,18 +144,18 @@ class TestFileJpeg(PillowTestCase):
# https://github.com/python-pillow/Pillow/issues/148
# Sometimes the meta data on the icc_profile block is bigger than
# Image.MAXBLOCK or the image size.
im = Image.open("Tests/images/icc_profile_big.jpg")
f = self.tempfile("temp.jpg")
icc_profile = im.info["icc_profile"]
# Should not raise IOError for image with icc larger than image size.
im.save(
f,
format="JPEG",
progressive=True,
quality=95,
icc_profile=icc_profile,
optimize=True,
)
with Image.open("Tests/images/icc_profile_big.jpg") as im:
f = self.tempfile("temp.jpg")
icc_profile = im.info["icc_profile"]
# Should not raise IOError for image with icc larger than image size.
im.save(
f,
format="JPEG",
progressive=True,
quality=95,
icc_profile=icc_profile,
optimize=True,
)
def test_optimize(self):
im1 = self.roundtrip(hopper())
@ -339,17 +343,17 @@ class TestFileJpeg(PillowTestCase):
def test_quality_keep(self):
# RGB
im = Image.open("Tests/images/hopper.jpg")
f = self.tempfile("temp.jpg")
im.save(f, quality="keep")
with Image.open("Tests/images/hopper.jpg") as im:
f = self.tempfile("temp.jpg")
im.save(f, quality="keep")
# Grayscale
im = Image.open("Tests/images/hopper_gray.jpg")
f = self.tempfile("temp.jpg")
im.save(f, quality="keep")
with Image.open("Tests/images/hopper_gray.jpg") as im:
f = self.tempfile("temp.jpg")
im.save(f, quality="keep")
# CMYK
im = Image.open("Tests/images/pil_sample_cmyk.jpg")
f = self.tempfile("temp.jpg")
im.save(f, quality="keep")
with Image.open("Tests/images/pil_sample_cmyk.jpg") as im:
f = self.tempfile("temp.jpg")
im.save(f, quality="keep")
def test_junk_jpeg_header(self):
# https://github.com/python-pillow/Pillow/issues/630
@ -365,10 +369,10 @@ class TestFileJpeg(PillowTestCase):
def test_truncated_jpeg_should_read_all_the_data(self):
filename = "Tests/images/truncated_jpeg.jpg"
ImageFile.LOAD_TRUNCATED_IMAGES = True
im = Image.open(filename)
im.load()
ImageFile.LOAD_TRUNCATED_IMAGES = False
self.assertIsNotNone(im.getbbox())
with Image.open(filename) as im:
im.load()
ImageFile.LOAD_TRUNCATED_IMAGES = False
self.assertIsNotNone(im.getbbox())
def test_truncated_jpeg_throws_IOError(self):
filename = "Tests/images/truncated_jpeg.jpg"
@ -381,106 +385,106 @@ class TestFileJpeg(PillowTestCase):
im.load()
def _n_qtables_helper(self, n, test_file):
im = Image.open(test_file)
f = self.tempfile("temp.jpg")
im.save(f, qtables=[[n] * 64] * n)
im = Image.open(f)
self.assertEqual(len(im.quantization), n)
reloaded = self.roundtrip(im, qtables="keep")
self.assertEqual(im.quantization, reloaded.quantization)
with Image.open(test_file) as im:
f = self.tempfile("temp.jpg")
im.save(f, qtables=[[n] * 64] * n)
with Image.open(f) as im:
self.assertEqual(len(im.quantization), n)
reloaded = self.roundtrip(im, qtables="keep")
self.assertEqual(im.quantization, reloaded.quantization)
def test_qtables(self):
im = Image.open("Tests/images/hopper.jpg")
qtables = im.quantization
reloaded = self.roundtrip(im, qtables=qtables, subsampling=0)
self.assertEqual(im.quantization, reloaded.quantization)
self.assert_image_similar(im, self.roundtrip(im, qtables="web_low"), 30)
self.assert_image_similar(im, self.roundtrip(im, qtables="web_high"), 30)
self.assert_image_similar(im, self.roundtrip(im, qtables="keep"), 30)
with Image.open("Tests/images/hopper.jpg") as im:
qtables = im.quantization
reloaded = self.roundtrip(im, qtables=qtables, subsampling=0)
self.assertEqual(im.quantization, reloaded.quantization)
self.assert_image_similar(im, self.roundtrip(im, qtables="web_low"), 30)
self.assert_image_similar(im, self.roundtrip(im, qtables="web_high"), 30)
self.assert_image_similar(im, self.roundtrip(im, qtables="keep"), 30)
# valid bounds for baseline qtable
bounds_qtable = [int(s) for s in ("255 1 " * 32).split(None)]
self.roundtrip(im, qtables=[bounds_qtable])
# valid bounds for baseline qtable
bounds_qtable = [int(s) for s in ("255 1 " * 32).split(None)]
self.roundtrip(im, qtables=[bounds_qtable])
# values from wizard.txt in jpeg9-a src package.
standard_l_qtable = [
int(s)
for s in """
16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99
""".split(
None
# values from wizard.txt in jpeg9-a src package.
standard_l_qtable = [
int(s)
for s in """
16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99
""".split(
None
)
]
standard_chrominance_qtable = [
int(s)
for s in """
17 18 24 47 99 99 99 99
18 21 26 66 99 99 99 99
24 26 56 99 99 99 99 99
47 66 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99
""".split(
None
)
]
# list of qtable lists
self.assert_image_similar(
im,
self.roundtrip(
im, qtables=[standard_l_qtable, standard_chrominance_qtable]
),
30,
)
]
standard_chrominance_qtable = [
int(s)
for s in """
17 18 24 47 99 99 99 99
18 21 26 66 99 99 99 99
24 26 56 99 99 99 99 99
47 66 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99
""".split(
None
# tuple of qtable lists
self.assert_image_similar(
im,
self.roundtrip(
im, qtables=(standard_l_qtable, standard_chrominance_qtable)
),
30,
)
]
# list of qtable lists
self.assert_image_similar(
im,
self.roundtrip(
im, qtables=[standard_l_qtable, standard_chrominance_qtable]
),
30,
)
# tuple of qtable lists
self.assert_image_similar(
im,
self.roundtrip(
im, qtables=(standard_l_qtable, standard_chrominance_qtable)
),
30,
)
# dict of qtable lists
self.assert_image_similar(
im,
self.roundtrip(
im, qtables={0: standard_l_qtable, 1: standard_chrominance_qtable}
),
30,
)
# dict of qtable lists
self.assert_image_similar(
im,
self.roundtrip(
im, qtables={0: standard_l_qtable, 1: standard_chrominance_qtable}
),
30,
)
self._n_qtables_helper(1, "Tests/images/hopper_gray.jpg")
self._n_qtables_helper(1, "Tests/images/pil_sample_rgb.jpg")
self._n_qtables_helper(2, "Tests/images/pil_sample_rgb.jpg")
self._n_qtables_helper(3, "Tests/images/pil_sample_rgb.jpg")
self._n_qtables_helper(1, "Tests/images/pil_sample_cmyk.jpg")
self._n_qtables_helper(2, "Tests/images/pil_sample_cmyk.jpg")
self._n_qtables_helper(3, "Tests/images/pil_sample_cmyk.jpg")
self._n_qtables_helper(4, "Tests/images/pil_sample_cmyk.jpg")
self._n_qtables_helper(1, "Tests/images/hopper_gray.jpg")
self._n_qtables_helper(1, "Tests/images/pil_sample_rgb.jpg")
self._n_qtables_helper(2, "Tests/images/pil_sample_rgb.jpg")
self._n_qtables_helper(3, "Tests/images/pil_sample_rgb.jpg")
self._n_qtables_helper(1, "Tests/images/pil_sample_cmyk.jpg")
self._n_qtables_helper(2, "Tests/images/pil_sample_cmyk.jpg")
self._n_qtables_helper(3, "Tests/images/pil_sample_cmyk.jpg")
self._n_qtables_helper(4, "Tests/images/pil_sample_cmyk.jpg")
# not a sequence
self.assertRaises(ValueError, self.roundtrip, im, qtables="a")
# sequence wrong length
self.assertRaises(ValueError, self.roundtrip, im, qtables=[])
# sequence wrong length
self.assertRaises(ValueError, self.roundtrip, im, qtables=[1, 2, 3, 4, 5])
# not a sequence
self.assertRaises(ValueError, self.roundtrip, im, qtables="a")
# sequence wrong length
self.assertRaises(ValueError, self.roundtrip, im, qtables=[])
# sequence wrong length
self.assertRaises(ValueError, self.roundtrip, im, qtables=[1, 2, 3, 4, 5])
# qtable entry not a sequence
self.assertRaises(ValueError, self.roundtrip, im, qtables=[1])
# qtable entry has wrong number of items
self.assertRaises(ValueError, self.roundtrip, im, qtables=[[1, 2, 3, 4]])
# qtable entry not a sequence
self.assertRaises(ValueError, self.roundtrip, im, qtables=[1])
# qtable entry has wrong number of items
self.assertRaises(ValueError, self.roundtrip, im, qtables=[[1, 2, 3, 4]])
@unittest.skipUnless(djpeg_available(), "djpeg not available")
def test_load_djpeg(self):
@ -490,12 +494,11 @@ class TestFileJpeg(PillowTestCase):
@unittest.skipUnless(cjpeg_available(), "cjpeg not available")
def test_save_cjpeg(self):
img = Image.open(TEST_FILE)
tempfile = self.tempfile("temp.jpg")
JpegImagePlugin._save_cjpeg(img, 0, tempfile)
# Default save quality is 75%, so a tiny bit of difference is alright
self.assert_image_similar(img, Image.open(tempfile), 17)
with Image.open(TEST_FILE) as img:
tempfile = self.tempfile("temp.jpg")
JpegImagePlugin._save_cjpeg(img, 0, tempfile)
# Default save quality is 75%, so a tiny bit of difference is alright
self.assert_image_similar(img, Image.open(tempfile), 17)
def test_no_duplicate_0x1001_tag(self):
# Arrange
@ -512,12 +515,11 @@ class TestFileJpeg(PillowTestCase):
f = self.tempfile("temp.jpeg")
im.save(f, quality=100, optimize=True)
reloaded = Image.open(f)
# none of these should crash
reloaded.save(f, quality="keep")
reloaded.save(f, quality="keep", progressive=True)
reloaded.save(f, quality="keep", optimize=True)
with Image.open(f) as reloaded:
# none of these should crash
reloaded.save(f, quality="keep")
reloaded.save(f, quality="keep", progressive=True)
reloaded.save(f, quality="keep", optimize=True)
def test_bad_mpo_header(self):
""" Treat unknown MPO as JPEG """
@ -547,15 +549,15 @@ class TestFileJpeg(PillowTestCase):
def test_save_tiff_with_dpi(self):
# Arrange
outfile = self.tempfile("temp.tif")
im = Image.open("Tests/images/hopper.tif")
with Image.open("Tests/images/hopper.tif") as im:
# Act
im.save(outfile, "JPEG", dpi=im.info["dpi"])
# Act
im.save(outfile, "JPEG", dpi=im.info["dpi"])
# Assert
reloaded = Image.open(outfile)
reloaded.load()
self.assertEqual(im.info["dpi"], reloaded.info["dpi"])
# Assert
with Image.open(outfile) as reloaded:
reloaded.load()
self.assertEqual(im.info["dpi"], reloaded.info["dpi"])
def test_load_dpi_rounding(self):
# Round up
@ -568,13 +570,14 @@ class TestFileJpeg(PillowTestCase):
def test_save_dpi_rounding(self):
outfile = self.tempfile("temp.jpg")
im = Image.open("Tests/images/hopper.jpg")
with Image.open("Tests/images/hopper.jpg") as im:
im.save(outfile, dpi=(72.2, 72.2))
im.save(outfile, dpi=(72.2, 72.2))
with Image.open(outfile) as reloaded:
self.assertEqual(reloaded.info["dpi"], (72, 72))
with Image.open(outfile) as reloaded:
self.assertEqual(reloaded.info["dpi"], (72, 72))
im.save(outfile, dpi=(72.8, 72.8))
with Image.open(outfile) as reloaded:
self.assertEqual(reloaded.info["dpi"], (73, 73))
@ -656,6 +659,11 @@ class TestFileJpeg(PillowTestCase):
},
)
# Test that the image can still load, even with broken Photoshop data
# This image had the APP13 length hexedited to be smaller
with Image.open("Tests/images/photoshop-200dpi-broken.jpg") as im_broken:
self.assert_image_equal(im_broken, im)
# This image does not contain a Photoshop header string
with Image.open("Tests/images/app13.jpg") as im:
self.assertNotIn("photoshop", im.info)

View File

@ -33,13 +33,13 @@ class TestFileJpeg2k(PillowTestCase):
# Internal version number
self.assertRegex(Image.core.jp2klib_version, r"\d+\.\d+\.\d+$")
im = Image.open("Tests/images/test-card-lossless.jp2")
px = im.load()
self.assertEqual(px[0, 0], (0, 0, 0))
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (640, 480))
self.assertEqual(im.format, "JPEG2000")
self.assertEqual(im.get_format_mimetype(), "image/jp2")
with Image.open("Tests/images/test-card-lossless.jp2") as im:
px = im.load()
self.assertEqual(px[0, 0], (0, 0, 0))
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (640, 480))
self.assertEqual(im.format, "JPEG2000")
self.assertEqual(im.get_format_mimetype(), "image/jp2")
def test_jpf(self):
with Image.open("Tests/images/balloon.jpf") as im:
@ -54,24 +54,24 @@ class TestFileJpeg2k(PillowTestCase):
def test_bytesio(self):
with open("Tests/images/test-card-lossless.jp2", "rb") as f:
data = BytesIO(f.read())
im = Image.open(data)
im.load()
self.assert_image_similar(im, test_card, 1.0e-3)
with Image.open(data) as im:
im.load()
self.assert_image_similar(im, test_card, 1.0e-3)
# These two test pre-written JPEG 2000 files that were not written with
# PIL (they were made using Adobe Photoshop)
def test_lossless(self):
im = Image.open("Tests/images/test-card-lossless.jp2")
im.load()
outfile = self.tempfile("temp_test-card.png")
im.save(outfile)
with Image.open("Tests/images/test-card-lossless.jp2") as im:
im.load()
outfile = self.tempfile("temp_test-card.png")
im.save(outfile)
self.assert_image_similar(im, test_card, 1.0e-3)
def test_lossy_tiled(self):
im = Image.open("Tests/images/test-card-lossy-tiled.jp2")
im.load()
self.assert_image_similar(im, test_card, 2.0)
with Image.open("Tests/images/test-card-lossy-tiled.jp2") as im:
im.load()
self.assert_image_similar(im, test_card, 2.0)
def test_lossless_rt(self):
im = self.roundtrip(test_card)
@ -110,10 +110,10 @@ class TestFileJpeg2k(PillowTestCase):
self.assert_image_equal(im, test_card)
def test_reduce(self):
im = Image.open("Tests/images/test-card-lossless.jp2")
im.reduce = 2
im.load()
self.assertEqual(im.size, (160, 120))
with Image.open("Tests/images/test-card-lossless.jp2") as im:
im.reduce = 2
im.load()
self.assertEqual(im.size, (160, 120))
def test_layers_type(self):
outfile = self.tempfile("temp_layers.jp2")
@ -132,64 +132,58 @@ class TestFileJpeg2k(PillowTestCase):
)
out.seek(0)
im = Image.open(out)
im.layers = 1
im.load()
self.assert_image_similar(im, test_card, 13)
with Image.open(out) as im:
im.layers = 1
im.load()
self.assert_image_similar(im, test_card, 13)
out.seek(0)
im = Image.open(out)
im.layers = 3
im.load()
self.assert_image_similar(im, test_card, 0.4)
with Image.open(out) as im:
im.layers = 3
im.load()
self.assert_image_similar(im, test_card, 0.4)
def test_rgba(self):
# Arrange
j2k = Image.open("Tests/images/rgb_trns_ycbc.j2k")
jp2 = Image.open("Tests/images/rgb_trns_ycbc.jp2")
with Image.open("Tests/images/rgb_trns_ycbc.j2k") as j2k:
with Image.open("Tests/images/rgb_trns_ycbc.jp2") as jp2:
# Act
j2k.load()
jp2.load()
# Act
j2k.load()
jp2.load()
# Assert
self.assertEqual(j2k.mode, "RGBA")
self.assertEqual(jp2.mode, "RGBA")
# Assert
self.assertEqual(j2k.mode, "RGBA")
self.assertEqual(jp2.mode, "RGBA")
def test_16bit_monochrome_has_correct_mode(self):
with Image.open("Tests/images/16bit.cropped.j2k") as j2k:
j2k.load()
self.assertEqual(j2k.mode, "I;16")
j2k = Image.open("Tests/images/16bit.cropped.j2k")
jp2 = Image.open("Tests/images/16bit.cropped.jp2")
j2k.load()
jp2.load()
self.assertEqual(j2k.mode, "I;16")
self.assertEqual(jp2.mode, "I;16")
with Image.open("Tests/images/16bit.cropped.jp2") as jp2:
jp2.load()
self.assertEqual(jp2.mode, "I;16")
def test_16bit_monochrome_jp2_like_tiff(self):
tiff_16bit = Image.open("Tests/images/16bit.cropped.tif")
jp2 = Image.open("Tests/images/16bit.cropped.jp2")
self.assert_image_similar(jp2, tiff_16bit, 1e-3)
with Image.open("Tests/images/16bit.cropped.tif") as tiff_16bit:
with Image.open("Tests/images/16bit.cropped.jp2") as jp2:
self.assert_image_similar(jp2, tiff_16bit, 1e-3)
def test_16bit_monochrome_j2k_like_tiff(self):
tiff_16bit = Image.open("Tests/images/16bit.cropped.tif")
j2k = Image.open("Tests/images/16bit.cropped.j2k")
self.assert_image_similar(j2k, tiff_16bit, 1e-3)
with Image.open("Tests/images/16bit.cropped.tif") as tiff_16bit:
with Image.open("Tests/images/16bit.cropped.j2k") as j2k:
self.assert_image_similar(j2k, tiff_16bit, 1e-3)
def test_16bit_j2k_roundtrips(self):
j2k = Image.open("Tests/images/16bit.cropped.j2k")
im = self.roundtrip(j2k)
self.assert_image_equal(im, j2k)
with Image.open("Tests/images/16bit.cropped.j2k") as j2k:
im = self.roundtrip(j2k)
self.assert_image_equal(im, j2k)
def test_16bit_jp2_roundtrips(self):
jp2 = Image.open("Tests/images/16bit.cropped.jp2")
im = self.roundtrip(jp2)
self.assert_image_equal(im, jp2)
with Image.open("Tests/images/16bit.cropped.jp2") as jp2:
im = self.roundtrip(jp2)
self.assert_image_equal(im, jp2)
def test_unbound_local(self):
# prepatch, a malformed jp2 file could cause an UnboundLocalError

View File

@ -1,5 +1,3 @@
from __future__ import print_function
import base64
import distutils.version
import io
@ -10,7 +8,6 @@ from collections import namedtuple
from ctypes import c_float
from PIL import Image, TiffImagePlugin, TiffTags, features
from PIL._util import py3
from .helper import PillowTestCase, hopper
@ -50,25 +47,23 @@ class TestFileLibTiff(LibTiffTestCase):
"""Test the ordinary file path load path"""
test_file = "Tests/images/hopper_g4_500.tif"
im = Image.open(test_file)
self.assertEqual(im.size, (500, 500))
self._assert_noerr(im)
with Image.open(test_file) as im:
self.assertEqual(im.size, (500, 500))
self._assert_noerr(im)
def test_g4_large(self):
test_file = "Tests/images/pport_g4.tif"
im = Image.open(test_file)
self._assert_noerr(im)
with Image.open(test_file) as im:
self._assert_noerr(im)
def test_g4_tiff_file(self):
"""Testing the string load path"""
test_file = "Tests/images/hopper_g4_500.tif"
with open(test_file, "rb") as f:
im = Image.open(f)
self.assertEqual(im.size, (500, 500))
self._assert_noerr(im)
with Image.open(f) as im:
self.assertEqual(im.size, (500, 500))
self._assert_noerr(im)
def test_g4_tiff_bytesio(self):
"""Testing the stringio loading code path"""
@ -77,10 +72,9 @@ class TestFileLibTiff(LibTiffTestCase):
with open(test_file, "rb") as f:
s.write(f.read())
s.seek(0)
im = Image.open(s)
self.assertEqual(im.size, (500, 500))
self._assert_noerr(im)
with Image.open(s) as im:
self.assertEqual(im.size, (500, 500))
self._assert_noerr(im)
def test_g4_non_disk_file_object(self):
"""Testing loading from non-disk non-BytesIO file object"""
@ -90,56 +84,51 @@ class TestFileLibTiff(LibTiffTestCase):
s.write(f.read())
s.seek(0)
r = io.BufferedReader(s)
im = Image.open(r)
self.assertEqual(im.size, (500, 500))
self._assert_noerr(im)
with Image.open(r) as im:
self.assertEqual(im.size, (500, 500))
self._assert_noerr(im)
def test_g4_eq_png(self):
""" Checking that we're actually getting the data that we expect"""
png = Image.open("Tests/images/hopper_bw_500.png")
g4 = Image.open("Tests/images/hopper_g4_500.tif")
self.assert_image_equal(g4, png)
with Image.open("Tests/images/hopper_bw_500.png") as png:
with Image.open("Tests/images/hopper_g4_500.tif") as g4:
self.assert_image_equal(g4, png)
# see https://github.com/python-pillow/Pillow/issues/279
def test_g4_fillorder_eq_png(self):
""" Checking that we're actually getting the data that we expect"""
png = Image.open("Tests/images/g4-fillorder-test.png")
g4 = Image.open("Tests/images/g4-fillorder-test.tif")
self.assert_image_equal(g4, png)
with Image.open("Tests/images/g4-fillorder-test.png") as png:
with Image.open("Tests/images/g4-fillorder-test.tif") as g4:
self.assert_image_equal(g4, png)
def test_g4_write(self):
"""Checking to see that the saved image is the same as what we wrote"""
test_file = "Tests/images/hopper_g4_500.tif"
orig = Image.open(test_file)
with Image.open(test_file) as orig:
out = self.tempfile("temp.tif")
rot = orig.transpose(Image.ROTATE_90)
self.assertEqual(rot.size, (500, 500))
rot.save(out)
out = self.tempfile("temp.tif")
rot = orig.transpose(Image.ROTATE_90)
self.assertEqual(rot.size, (500, 500))
rot.save(out)
with Image.open(out) as reread:
self.assertEqual(reread.size, (500, 500))
self._assert_noerr(reread)
self.assert_image_equal(reread, rot)
self.assertEqual(reread.info["compression"], "group4")
reread = Image.open(out)
self.assertEqual(reread.size, (500, 500))
self._assert_noerr(reread)
self.assert_image_equal(reread, rot)
self.assertEqual(reread.info["compression"], "group4")
self.assertEqual(reread.info["compression"], orig.info["compression"])
self.assertEqual(reread.info["compression"], orig.info["compression"])
self.assertNotEqual(orig.tobytes(), reread.tobytes())
self.assertNotEqual(orig.tobytes(), reread.tobytes())
def test_adobe_deflate_tiff(self):
test_file = "Tests/images/tiff_adobe_deflate.tif"
im = Image.open(test_file)
with Image.open(test_file) as im:
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (278, 374))
self.assertEqual(im.tile[0][:3], ("libtiff", (0, 0, 278, 374), 0))
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (278, 374))
self.assertEqual(im.tile[0][:3], ("libtiff", (0, 0, 278, 374), 0))
im.load()
self.assert_image_equal_tofile(im, "Tests/images/tiff_adobe_deflate.png")
self.assert_image_equal_tofile(im, "Tests/images/tiff_adobe_deflate.png")
def test_write_metadata(self):
""" Test metadata writing through libtiff """
@ -207,44 +196,44 @@ class TestFileLibTiff(LibTiffTestCase):
# Exclude ones that have special meaning
# that we're already testing them
im = Image.open("Tests/images/hopper_g4.tif")
for tag in im.tag_v2:
try:
del core_items[tag]
except KeyError:
pass
with Image.open("Tests/images/hopper_g4.tif") as im:
for tag in im.tag_v2:
try:
del core_items[tag]
except KeyError:
pass
# Type codes:
# 2: "ascii",
# 3: "short",
# 4: "long",
# 5: "rational",
# 12: "double",
# Type: dummy value
values = {
2: "test",
3: 1,
4: 2 ** 20,
5: TiffImagePlugin.IFDRational(100, 1),
12: 1.05,
}
# Type codes:
# 2: "ascii",
# 3: "short",
# 4: "long",
# 5: "rational",
# 12: "double",
# Type: dummy value
values = {
2: "test",
3: 1,
4: 2 ** 20,
5: TiffImagePlugin.IFDRational(100, 1),
12: 1.05,
}
new_ifd = TiffImagePlugin.ImageFileDirectory_v2()
for tag, info in core_items.items():
if info.length == 1:
new_ifd[tag] = values[info.type]
if info.length == 0:
new_ifd[tag] = tuple(values[info.type] for _ in range(3))
else:
new_ifd[tag] = tuple(values[info.type] for _ in range(info.length))
new_ifd = TiffImagePlugin.ImageFileDirectory_v2()
for tag, info in core_items.items():
if info.length == 1:
new_ifd[tag] = values[info.type]
if info.length == 0:
new_ifd[tag] = tuple(values[info.type] for _ in range(3))
else:
new_ifd[tag] = tuple(values[info.type] for _ in range(info.length))
# Extra samples really doesn't make sense in this application.
del new_ifd[338]
# Extra samples really doesn't make sense in this application.
del new_ifd[338]
out = self.tempfile("temp.tif")
TiffImagePlugin.WRITE_LIBTIFF = True
out = self.tempfile("temp.tif")
TiffImagePlugin.WRITE_LIBTIFF = True
im.save(out, tiffinfo=new_ifd)
im.save(out, tiffinfo=new_ifd)
TiffImagePlugin.WRITE_LIBTIFF = False
@ -263,7 +252,6 @@ class TestFileLibTiff(LibTiffTestCase):
tc(4.25, TiffTags.FLOAT, True),
tc(4.25, TiffTags.DOUBLE, True),
tc("custom tag value", TiffTags.ASCII, True),
tc(u"custom tag value", TiffTags.ASCII, True),
tc(b"custom tag value", TiffTags.BYTE, True),
tc((4, 5, 6), TiffTags.SHORT, True),
tc((123456789, 9, 34, 234, 219387, 92432323), TiffTags.LONG, True),
@ -346,70 +334,58 @@ class TestFileLibTiff(LibTiffTestCase):
self.assertEqual(reloaded.info["dpi"], (72.0, 72.0))
def test_g3_compression(self):
i = Image.open("Tests/images/hopper_g4_500.tif")
out = self.tempfile("temp.tif")
i.save(out, compression="group3")
with Image.open("Tests/images/hopper_g4_500.tif") as i:
out = self.tempfile("temp.tif")
i.save(out, compression="group3")
reread = Image.open(out)
self.assertEqual(reread.info["compression"], "group3")
self.assert_image_equal(reread, i)
with Image.open(out) as reread:
self.assertEqual(reread.info["compression"], "group3")
self.assert_image_equal(reread, i)
def test_little_endian(self):
im = Image.open("Tests/images/16bit.deflate.tif")
self.assertEqual(im.getpixel((0, 0)), 480)
self.assertEqual(im.mode, "I;16")
with Image.open("Tests/images/16bit.deflate.tif") as im:
self.assertEqual(im.getpixel((0, 0)), 480)
self.assertEqual(im.mode, "I;16")
b = im.tobytes()
# Bytes are in image native order (little endian)
if py3:
b = im.tobytes()
# Bytes are in image native order (little endian)
self.assertEqual(b[0], ord(b"\xe0"))
self.assertEqual(b[1], ord(b"\x01"))
else:
self.assertEqual(b[0], b"\xe0")
self.assertEqual(b[1], b"\x01")
out = self.tempfile("temp.tif")
# out = "temp.le.tif"
im.save(out)
reread = Image.open(out)
self.assertEqual(reread.info["compression"], im.info["compression"])
self.assertEqual(reread.getpixel((0, 0)), 480)
out = self.tempfile("temp.tif")
# out = "temp.le.tif"
im.save(out)
with Image.open(out) as reread:
self.assertEqual(reread.info["compression"], im.info["compression"])
self.assertEqual(reread.getpixel((0, 0)), 480)
# UNDONE - libtiff defaults to writing in native endian, so
# on big endian, we'll get back mode = 'I;16B' here.
def test_big_endian(self):
im = Image.open("Tests/images/16bit.MM.deflate.tif")
with Image.open("Tests/images/16bit.MM.deflate.tif") as im:
self.assertEqual(im.getpixel((0, 0)), 480)
self.assertEqual(im.mode, "I;16B")
self.assertEqual(im.getpixel((0, 0)), 480)
self.assertEqual(im.mode, "I;16B")
b = im.tobytes()
b = im.tobytes()
# Bytes are in image native order (big endian)
if py3:
# Bytes are in image native order (big endian)
self.assertEqual(b[0], ord(b"\x01"))
self.assertEqual(b[1], ord(b"\xe0"))
else:
self.assertEqual(b[0], b"\x01")
self.assertEqual(b[1], b"\xe0")
out = self.tempfile("temp.tif")
im.save(out)
reread = Image.open(out)
self.assertEqual(reread.info["compression"], im.info["compression"])
self.assertEqual(reread.getpixel((0, 0)), 480)
out = self.tempfile("temp.tif")
im.save(out)
with Image.open(out) as reread:
self.assertEqual(reread.info["compression"], im.info["compression"])
self.assertEqual(reread.getpixel((0, 0)), 480)
def test_g4_string_info(self):
"""Tests String data in info directory"""
test_file = "Tests/images/hopper_g4_500.tif"
orig = Image.open(test_file)
with Image.open(test_file) as orig:
out = self.tempfile("temp.tif")
out = self.tempfile("temp.tif")
orig.tag[269] = "temp.tif"
orig.save(out)
orig.tag[269] = "temp.tif"
orig.save(out)
with Image.open(out) as reread:
self.assertEqual("temp.tif", reread.tag_v2[269])
@ -419,16 +395,16 @@ class TestFileLibTiff(LibTiffTestCase):
""" Are we generating the same interpretation
of the image as Imagemagick is? """
TiffImagePlugin.READ_LIBTIFF = True
im = Image.open("Tests/images/12bit.cropped.tif")
im.load()
TiffImagePlugin.READ_LIBTIFF = False
# to make the target --
# convert 12bit.cropped.tif -depth 16 tmp.tif
# convert tmp.tif -evaluate RightShift 4 12in16bit2.tif
# imagemagick will auto scale so that a 12bit FFF is 16bit FFF0,
# so we need to unshift so that the integer values are the same.
with Image.open("Tests/images/12bit.cropped.tif") as im:
im.load()
TiffImagePlugin.READ_LIBTIFF = False
# to make the target --
# convert 12bit.cropped.tif -depth 16 tmp.tif
# convert tmp.tif -evaluate RightShift 4 12in16bit2.tif
# imagemagick will auto scale so that a 12bit FFF is 16bit FFF0,
# so we need to unshift so that the integer values are the same.
self.assert_image_equal_tofile(im, "Tests/images/12in16bit.tif")
self.assert_image_equal_tofile(im, "Tests/images/12in16bit.tif")
def test_blur(self):
# test case from irc, how to do blur on b/w image
@ -436,16 +412,16 @@ class TestFileLibTiff(LibTiffTestCase):
from PIL import ImageFilter
out = self.tempfile("temp.tif")
im = Image.open("Tests/images/pport_g4.tif")
im = im.convert("L")
with Image.open("Tests/images/pport_g4.tif") as im:
im = im.convert("L")
im = im.filter(ImageFilter.GaussianBlur(4))
im.save(out, compression="tiff_adobe_deflate")
im2 = Image.open(out)
im2.load()
with Image.open(out) as im2:
im2.load()
self.assert_image_equal(im, im2)
self.assert_image_equal(im, im2)
def test_compressions(self):
# Test various tiff compressions and assert similar image content but reduced
@ -458,18 +434,18 @@ class TestFileLibTiff(LibTiffTestCase):
for compression in ("packbits", "tiff_lzw"):
im.save(out, compression=compression)
size_compressed = os.path.getsize(out)
im2 = Image.open(out)
self.assert_image_equal(im, im2)
with Image.open(out) as im2:
self.assert_image_equal(im, im2)
im.save(out, compression="jpeg")
size_jpeg = os.path.getsize(out)
im2 = Image.open(out)
self.assert_image_similar(im, im2, 30)
with Image.open(out) as im2:
self.assert_image_similar(im, im2, 30)
im.save(out, compression="jpeg", quality=30)
size_jpeg_30 = os.path.getsize(out)
im3 = Image.open(out)
self.assert_image_similar(im2, im3, 30)
with Image.open(out) as im3:
self.assert_image_similar(im2, im3, 30)
self.assertGreater(size_raw, size_compressed)
self.assertGreater(size_compressed, size_jpeg)
@ -491,8 +467,8 @@ class TestFileLibTiff(LibTiffTestCase):
out = self.tempfile("temp.tif")
im.save(out, compression="tiff_adobe_deflate")
im2 = Image.open(out)
self.assert_image_equal(im, im2)
with Image.open(out) as im2:
self.assert_image_equal(im, im2)
def xtest_bw_compression_w_rgb(self):
""" This test passes, but when running all tests causes a failure due
@ -555,10 +531,10 @@ class TestFileLibTiff(LibTiffTestCase):
def test__next(self):
TiffImagePlugin.READ_LIBTIFF = True
im = Image.open("Tests/images/hopper.tif")
self.assertFalse(im.tag.next)
im.load()
self.assertFalse(im.tag.next)
with Image.open("Tests/images/hopper.tif") as im:
self.assertFalse(im.tag.next)
im.load()
self.assertFalse(im.tag.next)
def test_4bit(self):
# Arrange
@ -567,13 +543,13 @@ class TestFileLibTiff(LibTiffTestCase):
# Act
TiffImagePlugin.READ_LIBTIFF = True
im = Image.open(test_file)
TiffImagePlugin.READ_LIBTIFF = False
with Image.open(test_file) as im:
TiffImagePlugin.READ_LIBTIFF = False
# Assert
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.mode, "L")
self.assert_image_similar(im, original, 7.3)
# Assert
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.mode, "L")
self.assert_image_similar(im, original, 7.3)
def test_gray_semibyte_per_pixel(self):
test_files = (
@ -598,15 +574,15 @@ class TestFileLibTiff(LibTiffTestCase):
)
original = hopper("L")
for epsilon, group in test_files:
im = Image.open(group[0])
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.mode, "L")
self.assert_image_similar(im, original, epsilon)
with Image.open(group[0]) as im:
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.mode, "L")
self.assert_image_similar(im, original, epsilon)
for file in group[1:]:
im2 = Image.open(file)
self.assertEqual(im2.size, (128, 128))
self.assertEqual(im2.mode, "L")
self.assert_image_equal(im, im2)
with Image.open(file) as im2:
self.assertEqual(im2.size, (128, 128))
self.assertEqual(im2.mode, "L")
self.assert_image_equal(im, im2)
def test_save_bytesio(self):
# PR 1011
@ -624,8 +600,8 @@ class TestFileLibTiff(LibTiffTestCase):
pilim.save(buffer_io, format="tiff", compression=compression)
buffer_io.seek(0)
pilim_load = Image.open(buffer_io)
self.assert_image_similar(pilim, pilim_load, 0)
with Image.open(buffer_io) as pilim_load:
self.assert_image_similar(pilim, pilim_load, 0)
save_bytesio()
save_bytesio("raw")
@ -637,12 +613,12 @@ class TestFileLibTiff(LibTiffTestCase):
def test_crashing_metadata(self):
# issue 1597
im = Image.open("Tests/images/rdf.tif")
out = self.tempfile("temp.tif")
with Image.open("Tests/images/rdf.tif") as im:
out = self.tempfile("temp.tif")
TiffImagePlugin.WRITE_LIBTIFF = True
# this shouldn't crash
im.save(out, format="TIFF")
TiffImagePlugin.WRITE_LIBTIFF = True
# this shouldn't crash
im.save(out, format="TIFF")
TiffImagePlugin.WRITE_LIBTIFF = False
def test_page_number_x_0(self):
@ -708,44 +684,50 @@ class TestFileLibTiff(LibTiffTestCase):
# Created with ImageMagick: convert hopper.jpg hopper_jpg.tif
# Contains JPEGTables (347) tag
infile = "Tests/images/hopper_jpg.tif"
im = Image.open(infile)
# Act / Assert
# Should not raise UnicodeDecodeError or anything else
im.save(outfile)
with Image.open(infile) as im:
# Act / Assert
# Should not raise UnicodeDecodeError or anything else
im.save(outfile)
def test_16bit_RGB_tiff(self):
im = Image.open("Tests/images/tiff_16bit_RGB.tiff")
with Image.open("Tests/images/tiff_16bit_RGB.tiff") as im:
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (100, 40))
self.assertEqual(
im.tile,
[
(
"libtiff",
(0, 0, 100, 40),
0,
("RGB;16N", "tiff_adobe_deflate", False, 8),
)
],
)
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (100, 40))
self.assertEqual(
im.tile,
[
(
"libtiff",
(0, 0, 100, 40),
0,
("RGB;16N", "tiff_adobe_deflate", False, 8),
)
],
)
im.load()
self.assert_image_equal_tofile(im, "Tests/images/tiff_16bit_RGB_target.png")
self.assert_image_equal_tofile(im, "Tests/images/tiff_16bit_RGB_target.png")
def test_16bit_RGBa_tiff(self):
im = Image.open("Tests/images/tiff_16bit_RGBa.tiff")
with Image.open("Tests/images/tiff_16bit_RGBa.tiff") as im:
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (100, 40))
self.assertEqual(
im.tile,
[
(
"libtiff",
(0, 0, 100, 40),
0,
("RGBa;16N", "tiff_lzw", False, 38236),
)
],
)
im.load()
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (100, 40))
self.assertEqual(
im.tile,
[("libtiff", (0, 0, 100, 40), 0, ("RGBa;16N", "tiff_lzw", False, 38236))],
)
im.load()
self.assert_image_equal_tofile(im, "Tests/images/tiff_16bit_RGBa_target.png")
self.assert_image_equal_tofile(
im, "Tests/images/tiff_16bit_RGBa_target.png"
)
def test_gimp_tiff(self):
# Read TIFF JPEG images from GIMP [@PIL168]
@ -755,82 +737,79 @@ class TestFileLibTiff(LibTiffTestCase):
self.skipTest("jpeg support not available")
filename = "Tests/images/pil168.tif"
im = Image.open(filename)
with Image.open(filename) as im:
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (256, 256))
self.assertEqual(
im.tile,
[("libtiff", (0, 0, 256, 256), 0, ("RGB", "jpeg", False, 5122))],
)
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (256, 256))
self.assertEqual(
im.tile, [("libtiff", (0, 0, 256, 256), 0, ("RGB", "jpeg", False, 5122))]
)
im.load()
self.assert_image_equal_tofile(im, "Tests/images/pil168.png")
self.assert_image_equal_tofile(im, "Tests/images/pil168.png")
def test_sampleformat(self):
# https://github.com/python-pillow/Pillow/issues/1466
im = Image.open("Tests/images/copyleft.tiff")
self.assertEqual(im.mode, "RGB")
with Image.open("Tests/images/copyleft.tiff") as im:
self.assertEqual(im.mode, "RGB")
self.assert_image_equal_tofile(im, "Tests/images/copyleft.png", mode="RGB")
self.assert_image_equal_tofile(im, "Tests/images/copyleft.png", mode="RGB")
def test_lzw(self):
im = Image.open("Tests/images/hopper_lzw.tif")
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "TIFF")
im2 = hopper()
self.assert_image_similar(im, im2, 5)
with Image.open("Tests/images/hopper_lzw.tif") as im:
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "TIFF")
im2 = hopper()
self.assert_image_similar(im, im2, 5)
def test_strip_cmyk_jpeg(self):
infile = "Tests/images/tiff_strip_cmyk_jpeg.tif"
im = Image.open(infile)
self.assert_image_similar_tofile(im, "Tests/images/pil_sample_cmyk.jpg", 0.5)
with Image.open(infile) as im:
self.assert_image_similar_tofile(
im, "Tests/images/pil_sample_cmyk.jpg", 0.5
)
def test_strip_cmyk_16l_jpeg(self):
infile = "Tests/images/tiff_strip_cmyk_16l_jpeg.tif"
im = Image.open(infile)
self.assert_image_similar_tofile(im, "Tests/images/pil_sample_cmyk.jpg", 0.5)
with Image.open(infile) as im:
self.assert_image_similar_tofile(
im, "Tests/images/pil_sample_cmyk.jpg", 0.5
)
def test_strip_ycbcr_jpeg_2x2_sampling(self):
infile = "Tests/images/tiff_strip_ycbcr_jpeg_2x2_sampling.tif"
im = Image.open(infile)
self.assert_image_similar_tofile(im, "Tests/images/flower.jpg", 0.5)
with Image.open(infile) as im:
self.assert_image_similar_tofile(im, "Tests/images/flower.jpg", 0.5)
def test_strip_ycbcr_jpeg_1x1_sampling(self):
infile = "Tests/images/tiff_strip_ycbcr_jpeg_1x1_sampling.tif"
im = Image.open(infile)
self.assert_image_equal_tofile(im, "Tests/images/flower2.jpg")
with Image.open(infile) as im:
self.assert_image_equal_tofile(im, "Tests/images/flower2.jpg")
def test_tiled_cmyk_jpeg(self):
infile = "Tests/images/tiff_tiled_cmyk_jpeg.tif"
im = Image.open(infile)
self.assert_image_similar_tofile(im, "Tests/images/pil_sample_cmyk.jpg", 0.5)
with Image.open(infile) as im:
self.assert_image_similar_tofile(
im, "Tests/images/pil_sample_cmyk.jpg", 0.5
)
def test_tiled_ycbcr_jpeg_1x1_sampling(self):
infile = "Tests/images/tiff_tiled_ycbcr_jpeg_1x1_sampling.tif"
im = Image.open(infile)
self.assert_image_equal_tofile(im, "Tests/images/flower2.jpg")
with Image.open(infile) as im:
self.assert_image_equal_tofile(im, "Tests/images/flower2.jpg")
def test_tiled_ycbcr_jpeg_2x2_sampling(self):
infile = "Tests/images/tiff_tiled_ycbcr_jpeg_2x2_sampling.tif"
im = Image.open(infile)
self.assert_image_similar_tofile(im, "Tests/images/flower.jpg", 0.5)
with Image.open(infile) as im:
self.assert_image_similar_tofile(im, "Tests/images/flower.jpg", 0.5)
def test_old_style_jpeg(self):
infile = "Tests/images/old-style-jpeg-compression.tif"
im = Image.open(infile)
self.assert_image_equal_tofile(
im, "Tests/images/old-style-jpeg-compression.png"
)
with Image.open(infile) as im:
self.assert_image_equal_tofile(
im, "Tests/images/old-style-jpeg-compression.png"
)
def test_no_rows_per_strip(self):
# This image does not have a RowsPerStrip TIFF tag
@ -840,13 +819,12 @@ class TestFileLibTiff(LibTiffTestCase):
self.assertEqual(im.size, (950, 975))
def test_orientation(self):
base_im = Image.open("Tests/images/g4_orientation_1.tif")
with Image.open("Tests/images/g4_orientation_1.tif") as base_im:
for i in range(2, 9):
with Image.open("Tests/images/g4_orientation_" + str(i) + ".tif") as im:
im.load()
for i in range(2, 9):
im = Image.open("Tests/images/g4_orientation_" + str(i) + ".tif")
im.load()
self.assert_image_similar(base_im, im, 0.7)
self.assert_image_similar(base_im, im, 0.7)
def test_sampleformat_not_corrupted(self):
# Assert that a TIFF image with SampleFormat=UINT tag is not corrupted

View File

@ -20,10 +20,9 @@ class TestFileLibTiffSmall(LibTiffTestCase):
test_file = "Tests/images/hopper_g4.tif"
with open(test_file, "rb") as f:
im = Image.open(f)
self.assertEqual(im.size, (128, 128))
self._assert_noerr(im)
with Image.open(f) as im:
self.assertEqual(im.size, (128, 128))
self._assert_noerr(im)
def test_g4_hopper_bytesio(self):
"""Testing the bytesio loading code path"""
@ -32,16 +31,14 @@ class TestFileLibTiffSmall(LibTiffTestCase):
with open(test_file, "rb") as f:
s.write(f.read())
s.seek(0)
im = Image.open(s)
self.assertEqual(im.size, (128, 128))
self._assert_noerr(im)
with Image.open(s) as im:
self.assertEqual(im.size, (128, 128))
self._assert_noerr(im)
def test_g4_hopper(self):
"""The 128x128 lena image failed for some reason."""
test_file = "Tests/images/hopper_g4.tif"
im = Image.open(test_file)
self.assertEqual(im.size, (128, 128))
self._assert_noerr(im)
with Image.open(test_file) as im:
self.assertEqual(im.size, (128, 128))
self._assert_noerr(im)

View File

@ -17,12 +17,12 @@ class TestFileMcIdas(PillowTestCase):
saved_file = "Tests/images/cmx3g8_wv_1998.260_0745_mcidas.png"
# Act
im = Image.open(test_file)
im.load()
with Image.open(test_file) as im:
im.load()
# Assert
self.assertEqual(im.format, "MCIDAS")
self.assertEqual(im.mode, "I")
self.assertEqual(im.size, (1800, 400))
im2 = Image.open(saved_file)
self.assert_image_equal(im, im2)
# Assert
self.assertEqual(im.format, "MCIDAS")
self.assertEqual(im.mode, "I")
self.assertEqual(im.size, (1800, 400))
with Image.open(saved_file) as im2:
self.assert_image_equal(im, im2)

View File

@ -1,6 +1,8 @@
import unittest
from PIL import Image, ImagePalette, features
from .helper import PillowTestCase, hopper, unittest
from .helper import PillowTestCase, hopper
try:
from PIL import MicImagePlugin

View File

@ -113,6 +113,13 @@ class TestFileMpo(PillowTestCase):
self.assertEqual(mpinfo[45056], b"0100")
self.assertEqual(mpinfo[45057], 2)
def test_mp_no_data(self):
# This image has been manually hexedited to have the second frame
# beyond the end of the file
with Image.open("Tests/images/sugarshack_no_data.mpo") as im:
with self.assertRaises(ValueError):
im.seek(1)
def test_mp_attribute(self):
for test_file in test_files:
with Image.open(test_file) as im:

View File

@ -1,8 +1,9 @@
import os
import unittest
from PIL import Image, MspImagePlugin
from .helper import PillowTestCase, hopper, unittest
from .helper import PillowTestCase, hopper
TEST_FILE = "Tests/images/hopper.msp"
EXTRA_DIR = "Tests/images/picins"
@ -15,11 +16,11 @@ class TestFileMsp(PillowTestCase):
hopper("1").save(test_file)
im = Image.open(test_file)
im.load()
self.assertEqual(im.mode, "1")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "MSP")
with Image.open(test_file) as im:
im.load()
self.assertEqual(im.mode, "1")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "MSP")
def test_invalid_file(self):
invalid_file = "Tests/images/flower.jpg"
@ -37,16 +38,16 @@ class TestFileMsp(PillowTestCase):
def test_open_windows_v1(self):
# Arrange
# Act
im = Image.open(TEST_FILE)
with Image.open(TEST_FILE) as im:
# Assert
self.assert_image_equal(im, hopper("1"))
self.assertIsInstance(im, MspImagePlugin.MspImageFile)
# Assert
self.assert_image_equal(im, hopper("1"))
self.assertIsInstance(im, MspImagePlugin.MspImageFile)
def _assert_file_image_equal(self, source_path, target_path):
with Image.open(source_path) as im:
target = Image.open(target_path)
self.assert_image_equal(im, target)
with Image.open(target_path) as target:
self.assert_image_equal(im, target)
@unittest.skipIf(not os.path.exists(EXTRA_DIR), "Extra image files not installed")
def test_open_windows_v2(self):

View File

@ -5,8 +5,8 @@ from .helper import PillowTestCase
class TestFilePcd(PillowTestCase):
def test_load_raw(self):
im = Image.open("Tests/images/hopper.pcd")
im.load() # should not segfault.
with Image.open("Tests/images/hopper.pcd") as im:
im.load() # should not segfault.
# Note that this image was created with a resized hopper
# image, which was then converted to pcd with imagemagick

View File

@ -7,13 +7,12 @@ class TestFilePcx(PillowTestCase):
def _roundtrip(self, im):
f = self.tempfile("temp.pcx")
im.save(f)
im2 = Image.open(f)
self.assertEqual(im2.mode, im.mode)
self.assertEqual(im2.size, im.size)
self.assertEqual(im2.format, "PCX")
self.assertEqual(im2.get_format_mimetype(), "image/x-pcx")
self.assert_image_equal(im2, im)
with Image.open(f) as im2:
self.assertEqual(im2.mode, im.mode)
self.assertEqual(im2.size, im.size)
self.assertEqual(im2.format, "PCX")
self.assertEqual(im2.get_format_mimetype(), "image/x-pcx")
self.assert_image_equal(im2, im)
def test_sanity(self):
for mode in ("1", "L", "P", "RGB"):
@ -42,13 +41,12 @@ class TestFilePcx(PillowTestCase):
# Check reading of files where xmin/xmax is not zero.
test_file = "Tests/images/pil184.pcx"
im = Image.open(test_file)
with Image.open(test_file) as im:
self.assertEqual(im.size, (447, 144))
self.assertEqual(im.tile[0][1], (0, 0, 447, 144))
self.assertEqual(im.size, (447, 144))
self.assertEqual(im.tile[0][1], (0, 0, 447, 144))
# Make sure all pixels are either 0 or 255.
self.assertEqual(im.histogram()[0] + im.histogram()[255], 447 * 144)
# Make sure all pixels are either 0 or 255.
self.assertEqual(im.histogram()[0] + im.histogram()[255], 447 * 144)
def test_1px_width(self):
im = Image.new("L", (1, 256))

View File

@ -99,8 +99,7 @@ class TestFilePdf(PillowTestCase):
# Test appending using a generator
def imGenerator(ims):
for im in ims:
yield im
yield from ims
im.save(outfile, save_all=True, append_images=imGenerator(ims))
@ -108,8 +107,8 @@ class TestFilePdf(PillowTestCase):
self.assertGreater(os.path.getsize(outfile), 0)
# Append JPEG images
jpeg = Image.open("Tests/images/flower.jpg")
jpeg.save(outfile, save_all=True, append_images=[jpeg.copy()])
with Image.open("Tests/images/flower.jpg") as jpeg:
jpeg.save(outfile, save_all=True, append_images=[jpeg.copy()])
self.assertTrue(os.path.isfile(outfile))
self.assertGreater(os.path.getsize(outfile), 0)
@ -163,13 +162,10 @@ class TestFilePdf(PillowTestCase):
def test_pdf_append_fails_on_nonexistent_file(self):
im = hopper("RGB")
temp_dir = tempfile.mkdtemp()
try:
with tempfile.TemporaryDirectory() as temp_dir:
self.assertRaises(
IOError, im.save, os.path.join(temp_dir, "nonexistent.pdf"), append=True
)
finally:
os.rmdir(temp_dir)
def check_pdf_pages_consistency(self, pdf):
pages_info = pdf.read_indirect(pdf.pages_ref)
@ -207,7 +203,7 @@ class TestFilePdf(PillowTestCase):
# append some info
pdf.info.Title = "abc"
pdf.info.Author = "def"
pdf.info.Subject = u"ghi\uABCD"
pdf.info.Subject = "ghi\uABCD"
pdf.info.Keywords = "qw)e\\r(ty"
pdf.info.Creator = "hopper()"
pdf.start_writing()
@ -235,7 +231,7 @@ class TestFilePdf(PillowTestCase):
self.assertEqual(pdf.info.Title, "abc")
self.assertEqual(pdf.info.Producer, "PdfParser")
self.assertEqual(pdf.info.Keywords, "qw)e\\r(ty")
self.assertEqual(pdf.info.Subject, u"ghi\uABCD")
self.assertEqual(pdf.info.Subject, "ghi\uABCD")
self.assertIn(b"CreationDate", pdf.info)
self.assertIn(b"ModDate", pdf.info)
self.check_pdf_pages_consistency(pdf)

View File

@ -7,15 +7,15 @@ TEST_FILE = "Tests/images/hopper.pxr"
class TestFilePixar(PillowTestCase):
def test_sanity(self):
im = Image.open(TEST_FILE)
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "PIXAR")
self.assertIsNone(im.get_format_mimetype())
with Image.open(TEST_FILE) as im:
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "PIXAR")
self.assertIsNone(im.get_format_mimetype())
im2 = hopper()
self.assert_image_similar(im, im2, 4.8)
im2 = hopper()
self.assert_image_similar(im, im2, 4.8)
def test_invalid_file(self):
invalid_file = "Tests/images/flower.jpg"

View File

@ -1,10 +1,10 @@
import unittest
import zlib
from io import BytesIO
from PIL import Image, ImageFile, PngImagePlugin
from PIL._util import py3
from .helper import PillowLeakTestCase, PillowTestCase, hopper, is_win32, unittest
from .helper import PillowLeakTestCase, PillowTestCase, hopper, is_win32
try:
from PIL import _webp
@ -91,10 +91,10 @@ class TestFilePng(PillowTestCase):
for mode in ["1", "L", "P", "RGB", "I", "I;16"]:
im = hopper(mode)
im.save(test_file)
reloaded = Image.open(test_file)
if mode == "I;16":
reloaded = reloaded.convert(mode)
self.assert_image_equal(reloaded, im)
with Image.open(test_file) as reloaded:
if mode == "I;16":
reloaded = reloaded.convert(mode)
self.assert_image_equal(reloaded, im)
def test_invalid_file(self):
invalid_file = "Tests/images/flower.jpg"
@ -195,27 +195,24 @@ class TestFilePng(PillowTestCase):
def test_interlace(self):
test_file = "Tests/images/pil123p.png"
im = Image.open(test_file)
with Image.open(test_file) as im:
self.assert_image(im, "P", (162, 150))
self.assertTrue(im.info.get("interlace"))
self.assert_image(im, "P", (162, 150))
self.assertTrue(im.info.get("interlace"))
im.load()
im.load()
test_file = "Tests/images/pil123rgba.png"
im = Image.open(test_file)
with Image.open(test_file) as im:
self.assert_image(im, "RGBA", (162, 150))
self.assertTrue(im.info.get("interlace"))
self.assert_image(im, "RGBA", (162, 150))
self.assertTrue(im.info.get("interlace"))
im.load()
im.load()
def test_load_transparent_p(self):
test_file = "Tests/images/pil123p.png"
im = Image.open(test_file)
self.assert_image(im, "P", (162, 150))
im = im.convert("RGBA")
with Image.open(test_file) as im:
self.assert_image(im, "P", (162, 150))
im = im.convert("RGBA")
self.assert_image(im, "RGBA", (162, 150))
# image has 124 unique alpha values
@ -223,11 +220,11 @@ class TestFilePng(PillowTestCase):
def test_load_transparent_rgb(self):
test_file = "Tests/images/rgb_trns.png"
im = Image.open(test_file)
self.assertEqual(im.info["transparency"], (0, 255, 52))
with Image.open(test_file) as im:
self.assertEqual(im.info["transparency"], (0, 255, 52))
self.assert_image(im, "RGB", (64, 64))
im = im.convert("RGBA")
self.assert_image(im, "RGB", (64, 64))
im = im.convert("RGBA")
self.assert_image(im, "RGBA", (64, 64))
# image has 876 transparent pixels
@ -235,21 +232,20 @@ class TestFilePng(PillowTestCase):
def test_save_p_transparent_palette(self):
in_file = "Tests/images/pil123p.png"
im = Image.open(in_file)
with Image.open(in_file) as im:
# 'transparency' contains a byte string with the opacity for
# each palette entry
self.assertEqual(len(im.info["transparency"]), 256)
# 'transparency' contains a byte string with the opacity for
# each palette entry
self.assertEqual(len(im.info["transparency"]), 256)
test_file = self.tempfile("temp.png")
im.save(test_file)
test_file = self.tempfile("temp.png")
im.save(test_file)
# check if saved image contains same transparency
im = Image.open(test_file)
self.assertEqual(len(im.info["transparency"]), 256)
with Image.open(test_file) as im:
self.assertEqual(len(im.info["transparency"]), 256)
self.assert_image(im, "P", (162, 150))
im = im.convert("RGBA")
self.assert_image(im, "P", (162, 150))
im = im.convert("RGBA")
self.assert_image(im, "RGBA", (162, 150))
# image has 124 unique alpha values
@ -257,21 +253,20 @@ class TestFilePng(PillowTestCase):
def test_save_p_single_transparency(self):
in_file = "Tests/images/p_trns_single.png"
im = Image.open(in_file)
with Image.open(in_file) as im:
# pixel value 164 is full transparent
self.assertEqual(im.info["transparency"], 164)
self.assertEqual(im.getpixel((31, 31)), 164)
# pixel value 164 is full transparent
self.assertEqual(im.info["transparency"], 164)
self.assertEqual(im.getpixel((31, 31)), 164)
test_file = self.tempfile("temp.png")
im.save(test_file)
test_file = self.tempfile("temp.png")
im.save(test_file)
# check if saved image contains same transparency
im = Image.open(test_file)
self.assertEqual(im.info["transparency"], 164)
self.assertEqual(im.getpixel((31, 31)), 164)
self.assert_image(im, "P", (64, 64))
im = im.convert("RGBA")
with Image.open(test_file) as im:
self.assertEqual(im.info["transparency"], 164)
self.assertEqual(im.getpixel((31, 31)), 164)
self.assert_image(im, "P", (64, 64))
im = im.convert("RGBA")
self.assert_image(im, "RGBA", (64, 64))
self.assertEqual(im.getpixel((31, 31)), (0, 255, 52, 0))
@ -290,30 +285,30 @@ class TestFilePng(PillowTestCase):
im.save(test_file)
# check if saved image contains same transparency
im = Image.open(test_file)
self.assertEqual(len(im.info["transparency"]), 256)
self.assert_image(im, "P", (10, 10))
im = im.convert("RGBA")
with Image.open(test_file) as im:
self.assertEqual(len(im.info["transparency"]), 256)
self.assert_image(im, "P", (10, 10))
im = im.convert("RGBA")
self.assert_image(im, "RGBA", (10, 10))
self.assertEqual(im.getcolors(), [(100, (0, 0, 0, 0))])
def test_save_greyscale_transparency(self):
for mode, num_transparent in {"1": 1994, "L": 559, "I": 559}.items():
in_file = "Tests/images/" + mode.lower() + "_trns.png"
im = Image.open(in_file)
self.assertEqual(im.mode, mode)
self.assertEqual(im.info["transparency"], 255)
with Image.open(in_file) as im:
self.assertEqual(im.mode, mode)
self.assertEqual(im.info["transparency"], 255)
im_rgba = im.convert("RGBA")
im_rgba = im.convert("RGBA")
self.assertEqual(im_rgba.getchannel("A").getcolors()[0][0], num_transparent)
test_file = self.tempfile("temp.png")
im.save(test_file)
test_im = Image.open(test_file)
self.assertEqual(test_im.mode, mode)
self.assertEqual(test_im.info["transparency"], 255)
self.assert_image_equal(im, test_im)
with Image.open(test_file) as test_im:
self.assertEqual(test_im.mode, mode)
self.assertEqual(test_im.info["transparency"], 255)
self.assert_image_equal(im, test_im)
test_im_rgba = test_im.convert("RGBA")
self.assertEqual(
@ -322,22 +317,20 @@ class TestFilePng(PillowTestCase):
def test_save_rgb_single_transparency(self):
in_file = "Tests/images/caption_6_33_22.png"
im = Image.open(in_file)
test_file = self.tempfile("temp.png")
im.save(test_file)
with Image.open(in_file) as im:
test_file = self.tempfile("temp.png")
im.save(test_file)
def test_load_verify(self):
# Check open/load/verify exception (@PIL150)
im = Image.open(TEST_PNG_FILE)
with Image.open(TEST_PNG_FILE) as im:
# Assert that there is no unclosed file warning
self.assert_warning(None, im.verify)
# Assert that there is no unclosed file warning
self.assert_warning(None, im.verify)
im = Image.open(TEST_PNG_FILE)
im.load()
self.assertRaises(RuntimeError, im.verify)
with Image.open(TEST_PNG_FILE) as im:
im.load()
self.assertRaises(RuntimeError, im.verify)
def test_verify_struct_error(self):
# Check open/load/verify exception (#1755)
@ -350,9 +343,9 @@ class TestFilePng(PillowTestCase):
with open(TEST_PNG_FILE, "rb") as f:
test_file = f.read()[:offset]
im = Image.open(BytesIO(test_file))
self.assertIsNotNone(im.fp)
self.assertRaises((IOError, SyntaxError), im.verify)
with Image.open(BytesIO(test_file)) as im:
self.assertIsNotNone(im.fp)
self.assertRaises((IOError, SyntaxError), im.verify)
def test_verify_ignores_crc_error(self):
# check ignores crc errors in ancillary chunks
@ -386,9 +379,8 @@ class TestFilePng(PillowTestCase):
def test_roundtrip_dpi(self):
# Check dpi roundtripping
im = Image.open(TEST_PNG_FILE)
im = roundtrip(im, dpi=(100, 100))
with Image.open(TEST_PNG_FILE) as im:
im = roundtrip(im, dpi=(100, 100))
self.assertEqual(im.info["dpi"], (100, 100))
def test_load_dpi_rounding(self):
@ -401,9 +393,8 @@ class TestFilePng(PillowTestCase):
self.assertEqual(im.info["dpi"], (72, 72))
def test_save_dpi_rounding(self):
im = Image.open(TEST_PNG_FILE)
im = roundtrip(im, dpi=(72.2, 72.2))
with Image.open(TEST_PNG_FILE) as im:
im = roundtrip(im, dpi=(72.2, 72.2))
self.assertEqual(im.info["dpi"], (72, 72))
im = roundtrip(im, dpi=(72.8, 72.8))
@ -412,13 +403,12 @@ class TestFilePng(PillowTestCase):
def test_roundtrip_text(self):
# Check text roundtripping
im = Image.open(TEST_PNG_FILE)
with Image.open(TEST_PNG_FILE) as im:
info = PngImagePlugin.PngInfo()
info.add_text("TXT", "VALUE")
info.add_text("ZIP", "VALUE", zip=True)
info = PngImagePlugin.PngInfo()
info.add_text("TXT", "VALUE")
info.add_text("ZIP", "VALUE", zip=True)
im = roundtrip(im, pnginfo=info)
im = roundtrip(im, pnginfo=info)
self.assertEqual(im.info, {"TXT": "VALUE", "ZIP": "VALUE"})
self.assertEqual(im.text, {"TXT": "VALUE", "ZIP": "VALUE"})
@ -448,9 +438,7 @@ class TestFilePng(PillowTestCase):
self.assertIsInstance(im.info["Text"], str)
def test_unicode_text(self):
# Check preservation of non-ASCII characters on Python 3
# This cannot really be meaningfully tested on Python 2,
# since it didn't preserve charsets to begin with.
# Check preservation of non-ASCII characters
def rt_text(value):
im = Image.new("RGB", (32, 32))
@ -459,17 +447,11 @@ class TestFilePng(PillowTestCase):
im = roundtrip(im, pnginfo=info)
self.assertEqual(im.info, {"Text": value})
if py3:
rt_text(" Aa" + chr(0xA0) + chr(0xC4) + chr(0xFF)) # Latin1
rt_text(chr(0x400) + chr(0x472) + chr(0x4FF)) # Cyrillic
rt_text(
chr(0x4E00)
+ chr(0x66F0)
+ chr(0x9FBA) # CJK
+ chr(0x3042)
+ chr(0xAC00)
)
rt_text("A" + chr(0xC4) + chr(0x472) + chr(0x3042)) # Combined
rt_text(" Aa" + chr(0xA0) + chr(0xC4) + chr(0xFF)) # Latin1
rt_text(chr(0x400) + chr(0x472) + chr(0x4FF)) # Cyrillic
# CJK:
rt_text(chr(0x4E00) + chr(0x66F0) + chr(0x9FBA) + chr(0x3042) + chr(0xAC00))
rt_text("A" + chr(0xC4) + chr(0x472) + chr(0x3042)) # Combined
def test_scary(self):
# Check reading of evil PNG file. For information, see:
@ -488,11 +470,11 @@ class TestFilePng(PillowTestCase):
# Independent file sample provided by Sebastian Spaeth.
test_file = "Tests/images/caption_6_33_22.png"
im = Image.open(test_file)
self.assertEqual(im.info["transparency"], (248, 248, 248))
with Image.open(test_file) as im:
self.assertEqual(im.info["transparency"], (248, 248, 248))
# check saving transparency by default
im = roundtrip(im)
# check saving transparency by default
im = roundtrip(im)
self.assertEqual(im.info["transparency"], (248, 248, 248))
im = roundtrip(im, transparency=(0, 1, 2))
@ -506,10 +488,10 @@ class TestFilePng(PillowTestCase):
f = self.tempfile("temp.png")
im.save(f)
im2 = Image.open(f)
self.assertIn("transparency", im2.info)
with Image.open(f) as im2:
self.assertIn("transparency", im2.info)
self.assert_image_equal(im2.convert("RGBA"), im.convert("RGBA"))
self.assert_image_equal(im2.convert("RGBA"), im.convert("RGBA"))
def test_trns_null(self):
# Check reading images with null tRNS value, issue #1239
@ -529,36 +511,35 @@ class TestFilePng(PillowTestCase):
self.assertEqual(im.info["icc_profile"], expected_icc)
def test_discard_icc_profile(self):
im = Image.open("Tests/images/icc_profile.png")
im = roundtrip(im, icc_profile=None)
with Image.open("Tests/images/icc_profile.png") as im:
im = roundtrip(im, icc_profile=None)
self.assertNotIn("icc_profile", im.info)
def test_roundtrip_icc_profile(self):
im = Image.open("Tests/images/icc_profile.png")
expected_icc = im.info["icc_profile"]
with Image.open("Tests/images/icc_profile.png") as im:
expected_icc = im.info["icc_profile"]
im = roundtrip(im)
im = roundtrip(im)
self.assertEqual(im.info["icc_profile"], expected_icc)
def test_roundtrip_no_icc_profile(self):
im = Image.open("Tests/images/icc_profile_none.png")
self.assertIsNone(im.info["icc_profile"])
with Image.open("Tests/images/icc_profile_none.png") as im:
self.assertIsNone(im.info["icc_profile"])
im = roundtrip(im)
im = roundtrip(im)
self.assertNotIn("icc_profile", im.info)
def test_repr_png(self):
im = hopper()
repr_png = Image.open(BytesIO(im._repr_png_()))
self.assertEqual(repr_png.format, "PNG")
self.assert_image_equal(im, repr_png)
with Image.open(BytesIO(im._repr_png_())) as repr_png:
self.assertEqual(repr_png.format, "PNG")
self.assert_image_equal(im, repr_png)
def test_chunk_order(self):
im = Image.open("Tests/images/icc_profile.png")
test_file = self.tempfile("temp.png")
im.convert("P").save(test_file, dpi=(100, 100))
with Image.open("Tests/images/icc_profile.png") as im:
test_file = self.tempfile("temp.png")
im.convert("P").save(test_file, dpi=(100, 100))
chunks = self.get_chunks(test_file)
@ -583,61 +564,58 @@ class TestFilePng(PillowTestCase):
self.assertEqual(len(chunks), 3)
def test_textual_chunks_after_idat(self):
im = Image.open("Tests/images/hopper.png")
self.assertIn("comment", im.text.keys())
for k, v in {
"date:create": "2014-09-04T09:37:08+03:00",
"date:modify": "2014-09-04T09:37:08+03:00",
}.items():
self.assertEqual(im.text[k], v)
with Image.open("Tests/images/hopper.png") as im:
self.assertIn("comment", im.text.keys())
for k, v in {
"date:create": "2014-09-04T09:37:08+03:00",
"date:modify": "2014-09-04T09:37:08+03:00",
}.items():
self.assertEqual(im.text[k], v)
# Raises a SyntaxError in load_end
im = Image.open("Tests/images/broken_data_stream.png")
with self.assertRaises(IOError):
self.assertIsInstance(im.text, dict)
with Image.open("Tests/images/broken_data_stream.png") as im:
with self.assertRaises(IOError):
self.assertIsInstance(im.text, dict)
# Raises a UnicodeDecodeError in load_end
im = Image.open("Tests/images/truncated_image.png")
# The file is truncated
self.assertRaises(IOError, lambda: im.text)
ImageFile.LOAD_TRUNCATED_IMAGES = True
self.assertIsInstance(im.text, dict)
ImageFile.LOAD_TRUNCATED_IMAGES = False
with Image.open("Tests/images/truncated_image.png") as im:
# The file is truncated
self.assertRaises(IOError, lambda: im.text)
ImageFile.LOAD_TRUNCATED_IMAGES = True
self.assertIsInstance(im.text, dict)
ImageFile.LOAD_TRUNCATED_IMAGES = False
# Raises an EOFError in load_end
im = Image.open("Tests/images/hopper_idat_after_image_end.png")
self.assertEqual(im.text, {"TXT": "VALUE", "ZIP": "VALUE"})
with Image.open("Tests/images/hopper_idat_after_image_end.png") as im:
self.assertEqual(im.text, {"TXT": "VALUE", "ZIP": "VALUE"})
def test_exif(self):
im = Image.open("Tests/images/exif.png")
exif = im._getexif()
with Image.open("Tests/images/exif.png") as im:
exif = im._getexif()
self.assertEqual(exif[274], 1)
def test_exif_save(self):
im = Image.open("Tests/images/exif.png")
test_file = self.tempfile("temp.png")
im.save(test_file)
with Image.open("Tests/images/exif.png") as im:
test_file = self.tempfile("temp.png")
im.save(test_file)
with Image.open(test_file) as reloaded:
exif = reloaded._getexif()
self.assertEqual(exif[274], 1)
def test_exif_from_jpg(self):
im = Image.open("Tests/images/pil_sample_rgb.jpg")
test_file = self.tempfile("temp.png")
im.save(test_file)
with Image.open("Tests/images/pil_sample_rgb.jpg") as im:
test_file = self.tempfile("temp.png")
im.save(test_file)
with Image.open(test_file) as reloaded:
exif = reloaded._getexif()
self.assertEqual(exif[305], "Adobe Photoshop CS Macintosh")
def test_exif_argument(self):
im = Image.open(TEST_PNG_FILE)
test_file = self.tempfile("temp.png")
im.save(test_file, exif=b"exifstring")
with Image.open(TEST_PNG_FILE) as im:
test_file = self.tempfile("temp.png")
im.save(test_file, exif=b"exifstring")
with Image.open(test_file) as reloaded:
self.assertEqual(reloaded.info["exif"], b"Exif\x00\x00exifstring")
@ -646,12 +624,12 @@ class TestFilePng(PillowTestCase):
HAVE_WEBP and _webp.HAVE_WEBPANIM, "WebP support not installed with animation"
)
def test_apng(self):
im = Image.open("Tests/images/iss634.apng")
self.assertEqual(im.get_format_mimetype(), "image/apng")
with Image.open("Tests/images/iss634.apng") as im:
self.assertEqual(im.get_format_mimetype(), "image/apng")
# This also tests reading unknown PNG chunks (fcTL and fdAT) in load_end
expected = Image.open("Tests/images/iss634.webp")
self.assert_image_similar(im, expected, 0.23)
# This also tests reading unknown PNG chunks (fcTL and fdAT) in load_end
with Image.open("Tests/images/iss634.webp") as expected:
self.assert_image_similar(im, expected, 0.23)
@unittest.skipIf(is_win32(), "requires Unix or macOS")

View File

@ -8,42 +8,42 @@ test_file = "Tests/images/hopper.ppm"
class TestFilePpm(PillowTestCase):
def test_sanity(self):
im = Image.open(test_file)
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "PPM")
self.assertEqual(im.get_format_mimetype(), "image/x-portable-pixmap")
with Image.open(test_file) as im:
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "PPM")
self.assertEqual(im.get_format_mimetype(), "image/x-portable-pixmap")
def test_16bit_pgm(self):
im = Image.open("Tests/images/16_bit_binary.pgm")
im.load()
self.assertEqual(im.mode, "I")
self.assertEqual(im.size, (20, 100))
self.assertEqual(im.get_format_mimetype(), "image/x-portable-graymap")
with Image.open("Tests/images/16_bit_binary.pgm") as im:
im.load()
self.assertEqual(im.mode, "I")
self.assertEqual(im.size, (20, 100))
self.assertEqual(im.get_format_mimetype(), "image/x-portable-graymap")
tgt = Image.open("Tests/images/16_bit_binary_pgm.png")
self.assert_image_equal(im, tgt)
with Image.open("Tests/images/16_bit_binary_pgm.png") as tgt:
self.assert_image_equal(im, tgt)
def test_16bit_pgm_write(self):
im = Image.open("Tests/images/16_bit_binary.pgm")
im.load()
with Image.open("Tests/images/16_bit_binary.pgm") as im:
im.load()
f = self.tempfile("temp.pgm")
im.save(f, "PPM")
f = self.tempfile("temp.pgm")
im.save(f, "PPM")
reloaded = Image.open(f)
self.assert_image_equal(im, reloaded)
with Image.open(f) as reloaded:
self.assert_image_equal(im, reloaded)
def test_pnm(self):
im = Image.open("Tests/images/hopper.pnm")
self.assert_image_similar(im, hopper(), 0.0001)
with Image.open("Tests/images/hopper.pnm") as im:
self.assert_image_similar(im, hopper(), 0.0001)
f = self.tempfile("temp.pnm")
im.save(f)
f = self.tempfile("temp.pnm")
im.save(f)
reloaded = Image.open(f)
self.assert_image_equal(im, reloaded)
with Image.open(f) as reloaded:
self.assert_image_equal(im, reloaded)
def test_truncated_file(self):
path = self.tempfile("temp.pgm")

View File

@ -9,50 +9,50 @@ class TestFileSgi(PillowTestCase):
# convert hopper.ppm -compress None sgi:hopper.rgb
test_file = "Tests/images/hopper.rgb"
im = Image.open(test_file)
self.assert_image_equal(im, hopper())
self.assertEqual(im.get_format_mimetype(), "image/rgb")
with Image.open(test_file) as im:
self.assert_image_equal(im, hopper())
self.assertEqual(im.get_format_mimetype(), "image/rgb")
def test_rgb16(self):
test_file = "Tests/images/hopper16.rgb"
im = Image.open(test_file)
self.assert_image_equal(im, hopper())
with Image.open(test_file) as im:
self.assert_image_equal(im, hopper())
def test_l(self):
# Created with ImageMagick
# convert hopper.ppm -monochrome -compress None sgi:hopper.bw
test_file = "Tests/images/hopper.bw"
im = Image.open(test_file)
self.assert_image_similar(im, hopper("L"), 2)
self.assertEqual(im.get_format_mimetype(), "image/sgi")
with Image.open(test_file) as im:
self.assert_image_similar(im, hopper("L"), 2)
self.assertEqual(im.get_format_mimetype(), "image/sgi")
def test_rgba(self):
# Created with ImageMagick:
# convert transparent.png -compress None transparent.sgi
test_file = "Tests/images/transparent.sgi"
im = Image.open(test_file)
target = Image.open("Tests/images/transparent.png")
self.assert_image_equal(im, target)
self.assertEqual(im.get_format_mimetype(), "image/sgi")
with Image.open(test_file) as im:
with Image.open("Tests/images/transparent.png") as target:
self.assert_image_equal(im, target)
self.assertEqual(im.get_format_mimetype(), "image/sgi")
def test_rle(self):
# Created with ImageMagick:
# convert hopper.ppm hopper.sgi
test_file = "Tests/images/hopper.sgi"
im = Image.open(test_file)
target = Image.open("Tests/images/hopper.rgb")
self.assert_image_equal(im, target)
with Image.open(test_file) as im:
with Image.open("Tests/images/hopper.rgb") as target:
self.assert_image_equal(im, target)
def test_rle16(self):
test_file = "Tests/images/tv16.sgi"
im = Image.open(test_file)
target = Image.open("Tests/images/tv.rgb")
self.assert_image_equal(im, target)
with Image.open(test_file) as im:
with Image.open("Tests/images/tv.rgb") as target:
self.assert_image_equal(im, target)
def test_invalid_file(self):
invalid_file = "Tests/images/flower.jpg"
@ -63,8 +63,8 @@ class TestFileSgi(PillowTestCase):
def roundtrip(img):
out = self.tempfile("temp.sgi")
img.save(out, format="sgi")
reloaded = Image.open(out)
self.assert_image_equal(img, reloaded)
with Image.open(out) as reloaded:
self.assert_image_equal(img, reloaded)
for mode in ("L", "RGB", "RGBA"):
roundtrip(hopper(mode))
@ -75,12 +75,12 @@ class TestFileSgi(PillowTestCase):
def test_write16(self):
test_file = "Tests/images/hopper16.rgb"
im = Image.open(test_file)
out = self.tempfile("temp.sgi")
im.save(out, format="sgi", bpc=2)
with Image.open(test_file) as im:
out = self.tempfile("temp.sgi")
im.save(out, format="sgi", bpc=2)
reloaded = Image.open(out)
self.assert_image_equal(im, reloaded)
with Image.open(out) as reloaded:
self.assert_image_equal(im, reloaded)
def test_unsupported_mode(self):
im = hopper("LA")

View File

@ -64,10 +64,10 @@ class TestImageSpider(PillowTestCase):
# Assert
fp.seek(0)
reloaded = Image.open(fp)
self.assertEqual(reloaded.mode, "F")
self.assertEqual(reloaded.size, (128, 128))
self.assertEqual(reloaded.format, "SPIDER")
with Image.open(fp) as reloaded:
self.assertEqual(reloaded.mode, "F")
self.assertEqual(reloaded.size, (128, 128))
self.assertEqual(reloaded.format, "SPIDER")
def test_isSpiderImage(self):
self.assertTrue(SpiderImagePlugin.isSpiderImage(TEST_FILE))
@ -143,5 +143,5 @@ class TestImageSpider(PillowTestCase):
im.save(data, format="SPIDER")
data.seek(0)
im2 = Image.open(data)
self.assert_image_equal(im, im2)
with Image.open(data) as im2:
self.assert_image_equal(im, im2)

View File

@ -1,8 +1,9 @@
import os
import unittest
from PIL import Image, SunImagePlugin
from .helper import PillowTestCase, hopper, unittest
from .helper import PillowTestCase, hopper
EXTRA_DIR = "Tests/images/sunraster"
@ -14,20 +15,20 @@ class TestFileSun(PillowTestCase):
test_file = "Tests/images/hopper.ras"
# Act
im = Image.open(test_file)
with Image.open(test_file) as im:
# Assert
self.assertEqual(im.size, (128, 128))
# Assert
self.assertEqual(im.size, (128, 128))
self.assert_image_similar(im, hopper(), 5) # visually verified
self.assert_image_similar(im, hopper(), 5) # visually verified
invalid_file = "Tests/images/flower.jpg"
self.assertRaises(SyntaxError, SunImagePlugin.SunImageFile, invalid_file)
def test_im1(self):
im = Image.open("Tests/images/sunraster.im1")
target = Image.open("Tests/images/sunraster.im1.png")
self.assert_image_equal(im, target)
with Image.open("Tests/images/sunraster.im1") as im:
with Image.open("Tests/images/sunraster.im1.png") as target:
self.assert_image_equal(im, target)
@unittest.skipIf(not os.path.exists(EXTRA_DIR), "Extra image files not installed")
def test_others(self):

View File

@ -22,11 +22,11 @@ class TestFileTar(PillowTestCase):
]:
if codec in codecs:
with TarIO.TarIO(TEST_TAR_FILE, test_path) as tar:
im = Image.open(tar)
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, format)
with Image.open(tar) as im:
im.load()
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, format)
@unittest.skipIf(is_pypy(), "Requires CPython")
def test_unclosed_file(self):

View File

@ -24,52 +24,57 @@ class TestFileTga(PillowTestCase):
)
for png_path in png_paths:
reference_im = Image.open(png_path)
self.assertEqual(reference_im.mode, mode)
with Image.open(png_path) as reference_im:
self.assertEqual(reference_im.mode, mode)
path_no_ext = os.path.splitext(png_path)[0]
for origin, rle in product(self._ORIGINS, (True, False)):
tga_path = "{}_{}_{}.tga".format(
path_no_ext, origin, "rle" if rle else "raw"
)
original_im = Image.open(tga_path)
self.assertEqual(original_im.format, "TGA")
self.assertEqual(original_im.get_format_mimetype(), "image/x-tga")
if rle:
self.assertEqual(original_im.info["compression"], "tga_rle")
self.assertEqual(
original_im.info["orientation"],
self._ORIGIN_TO_ORIENTATION[origin],
)
if mode == "P":
self.assertEqual(
original_im.getpalette(), reference_im.getpalette()
path_no_ext = os.path.splitext(png_path)[0]
for origin, rle in product(self._ORIGINS, (True, False)):
tga_path = "{}_{}_{}.tga".format(
path_no_ext, origin, "rle" if rle else "raw"
)
self.assert_image_equal(original_im, reference_im)
with Image.open(tga_path) as original_im:
self.assertEqual(original_im.format, "TGA")
self.assertEqual(
original_im.get_format_mimetype(), "image/x-tga"
)
if rle:
self.assertEqual(
original_im.info["compression"], "tga_rle"
)
self.assertEqual(
original_im.info["orientation"],
self._ORIGIN_TO_ORIENTATION[origin],
)
if mode == "P":
self.assertEqual(
original_im.getpalette(), reference_im.getpalette()
)
# Generate a new test name every time so the
# test will not fail with permission error
# on Windows.
out = self.tempfile("temp.tga")
self.assert_image_equal(original_im, reference_im)
original_im.save(out, rle=rle)
saved_im = Image.open(out)
if rle:
self.assertEqual(
saved_im.info["compression"],
original_im.info["compression"],
)
self.assertEqual(
saved_im.info["orientation"], original_im.info["orientation"]
)
if mode == "P":
self.assertEqual(
saved_im.getpalette(), original_im.getpalette()
)
# Generate a new test name every time so the
# test will not fail with permission error
# on Windows.
out = self.tempfile("temp.tga")
self.assert_image_equal(saved_im, original_im)
original_im.save(out, rle=rle)
with Image.open(out) as saved_im:
if rle:
self.assertEqual(
saved_im.info["compression"],
original_im.info["compression"],
)
self.assertEqual(
saved_im.info["orientation"],
original_im.info["orientation"],
)
if mode == "P":
self.assertEqual(
saved_im.getpalette(), original_im.getpalette()
)
self.assert_image_equal(saved_im, original_im)
def test_id_field(self):
# tga file with id field
@ -93,29 +98,27 @@ class TestFileTga(PillowTestCase):
def test_save(self):
test_file = "Tests/images/tga_id_field.tga"
im = Image.open(test_file)
with Image.open(test_file) as im:
out = self.tempfile("temp.tga")
out = self.tempfile("temp.tga")
# Save
im.save(out)
with Image.open(out) as test_im:
self.assertEqual(test_im.size, (100, 100))
self.assertEqual(test_im.info["id_section"], im.info["id_section"])
# Save
im.save(out)
with Image.open(out) as test_im:
self.assertEqual(test_im.size, (100, 100))
self.assertEqual(test_im.info["id_section"], im.info["id_section"])
# RGBA save
im.convert("RGBA").save(out)
# RGBA save
im.convert("RGBA").save(out)
with Image.open(out) as test_im:
self.assertEqual(test_im.size, (100, 100))
def test_save_id_section(self):
test_file = "Tests/images/rgb32rle.tga"
im = Image.open(test_file)
with Image.open(test_file) as im:
out = self.tempfile("temp.tga")
out = self.tempfile("temp.tga")
# Check there is no id section
im.save(out)
# Check there is no id section
im.save(out)
with Image.open(out) as test_im:
self.assertNotIn("id_section", test_im.info)
@ -140,24 +143,23 @@ class TestFileTga(PillowTestCase):
def test_save_orientation(self):
test_file = "Tests/images/rgb32rle.tga"
im = Image.open(test_file)
self.assertEqual(im.info["orientation"], -1)
out = self.tempfile("temp.tga")
with Image.open(test_file) as im:
self.assertEqual(im.info["orientation"], -1)
im.save(out, orientation=1)
im.save(out, orientation=1)
with Image.open(out) as test_im:
self.assertEqual(test_im.info["orientation"], 1)
def test_save_rle(self):
test_file = "Tests/images/rgb32rle.tga"
im = Image.open(test_file)
self.assertEqual(im.info["compression"], "tga_rle")
with Image.open(test_file) as im:
self.assertEqual(im.info["compression"], "tga_rle")
out = self.tempfile("temp.tga")
out = self.tempfile("temp.tga")
# Save
im.save(out)
# Save
im.save(out)
with Image.open(out) as test_im:
self.assertEqual(test_im.size, (199, 199))
self.assertEqual(test_im.info["compression"], "tga_rle")
@ -173,11 +175,11 @@ class TestFileTga(PillowTestCase):
self.assertEqual(test_im.size, (199, 199))
test_file = "Tests/images/tga_id_field.tga"
im = Image.open(test_file)
self.assertNotIn("compression", im.info)
with Image.open(test_file) as im:
self.assertNotIn("compression", im.info)
# Save with compression
im.save(out, compression="tga_rle")
# Save with compression
im.save(out, compression="tga_rle")
with Image.open(out) as test_im:
self.assertEqual(test_im.info["compression"], "tga_rle")
@ -186,15 +188,15 @@ class TestFileTga(PillowTestCase):
num_transparent = 559
in_file = "Tests/images/la.tga"
im = Image.open(in_file)
self.assertEqual(im.mode, "LA")
self.assertEqual(im.getchannel("A").getcolors()[0][0], num_transparent)
with Image.open(in_file) as im:
self.assertEqual(im.mode, "LA")
self.assertEqual(im.getchannel("A").getcolors()[0][0], num_transparent)
out = self.tempfile("temp.tga")
im.save(out)
out = self.tempfile("temp.tga")
im.save(out)
test_im = Image.open(out)
self.assertEqual(test_im.mode, "LA")
self.assertEqual(test_im.getchannel("A").getcolors()[0][0], num_transparent)
with Image.open(out) as test_im:
self.assertEqual(test_im.mode, "LA")
self.assertEqual(test_im.getchannel("A").getcolors()[0][0], num_transparent)
self.assert_image_equal(im, test_im)
self.assert_image_equal(im, test_im)

View File

@ -1,13 +1,13 @@
import logging
import os
import unittest
from io import BytesIO
import pytest
from PIL import Image, TiffImagePlugin
from PIL._util import py3
from PIL.TiffImagePlugin import RESOLUTION_UNIT, X_RESOLUTION, Y_RESOLUTION
from .helper import PillowTestCase, hopper, is_pypy, is_win32, unittest
from .helper import PillowTestCase, hopper, is_pypy, is_win32
logger = logging.getLogger(__name__)
@ -72,22 +72,20 @@ class TestFileTiff(PillowTestCase):
# Read RGBa images from macOS [@PIL136]
filename = "Tests/images/pil136.tiff"
im = Image.open(filename)
with Image.open(filename) as im:
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (55, 43))
self.assertEqual(im.tile, [("raw", (0, 0, 55, 43), 8, ("RGBa", 0, 1))])
im.load()
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (55, 43))
self.assertEqual(im.tile, [("raw", (0, 0, 55, 43), 8, ("RGBa", 0, 1))])
im.load()
self.assert_image_similar_tofile(im, "Tests/images/pil136.png", 1)
self.assert_image_similar_tofile(im, "Tests/images/pil136.png", 1)
def test_wrong_bits_per_sample(self):
im = Image.open("Tests/images/tiff_wrong_bits_per_sample.tiff")
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (52, 53))
self.assertEqual(im.tile, [("raw", (0, 0, 52, 53), 160, ("RGBA", 0, 1))])
im.load()
with Image.open("Tests/images/tiff_wrong_bits_per_sample.tiff") as im:
self.assertEqual(im.mode, "RGBA")
self.assertEqual(im.size, (52, 53))
self.assertEqual(im.tile, [("raw", (0, 0, 52, 53), 160, ("RGBA", 0, 1))])
im.load()
def test_set_legacy_api(self):
ifd = TiffImagePlugin.ImageFileDirectory_v2()
@ -149,23 +147,22 @@ class TestFileTiff(PillowTestCase):
def test_save_dpi_rounding(self):
outfile = self.tempfile("temp.tif")
im = Image.open("Tests/images/hopper.tif")
with Image.open("Tests/images/hopper.tif") as im:
for dpi in (72.2, 72.8):
im.save(outfile, dpi=(dpi, dpi))
for dpi in (72.2, 72.8):
im.save(outfile, dpi=(dpi, dpi))
reloaded = Image.open(outfile)
reloaded.load()
self.assertEqual((round(dpi), round(dpi)), reloaded.info["dpi"])
with Image.open(outfile) as reloaded:
reloaded.load()
self.assertEqual((round(dpi), round(dpi)), reloaded.info["dpi"])
def test_save_setting_missing_resolution(self):
b = BytesIO()
Image.open("Tests/images/10ct_32bit_128.tiff").save(
b, format="tiff", resolution=123.45
)
im = Image.open(b)
self.assertEqual(float(im.tag_v2[X_RESOLUTION]), 123.45)
self.assertEqual(float(im.tag_v2[Y_RESOLUTION]), 123.45)
with Image.open(b) as im:
self.assertEqual(float(im.tag_v2[X_RESOLUTION]), 123.45)
self.assertEqual(float(im.tag_v2[Y_RESOLUTION]), 123.45)
def test_invalid_file(self):
invalid_file = "Tests/images/flower.jpg"
@ -192,63 +189,53 @@ class TestFileTiff(PillowTestCase):
self.assertRaises(IOError, im.save, outfile)
def test_little_endian(self):
im = Image.open("Tests/images/16bit.cropped.tif")
self.assertEqual(im.getpixel((0, 0)), 480)
self.assertEqual(im.mode, "I;16")
with Image.open("Tests/images/16bit.cropped.tif") as im:
self.assertEqual(im.getpixel((0, 0)), 480)
self.assertEqual(im.mode, "I;16")
b = im.tobytes()
b = im.tobytes()
# Bytes are in image native order (little endian)
if py3:
self.assertEqual(b[0], ord(b"\xe0"))
self.assertEqual(b[1], ord(b"\x01"))
else:
self.assertEqual(b[0], b"\xe0")
self.assertEqual(b[1], b"\x01")
self.assertEqual(b[0], ord(b"\xe0"))
self.assertEqual(b[1], ord(b"\x01"))
def test_big_endian(self):
im = Image.open("Tests/images/16bit.MM.cropped.tif")
self.assertEqual(im.getpixel((0, 0)), 480)
self.assertEqual(im.mode, "I;16B")
b = im.tobytes()
with Image.open("Tests/images/16bit.MM.cropped.tif") as im:
self.assertEqual(im.getpixel((0, 0)), 480)
self.assertEqual(im.mode, "I;16B")
b = im.tobytes()
# Bytes are in image native order (big endian)
if py3:
self.assertEqual(b[0], ord(b"\x01"))
self.assertEqual(b[1], ord(b"\xe0"))
else:
self.assertEqual(b[0], b"\x01")
self.assertEqual(b[1], b"\xe0")
self.assertEqual(b[0], ord(b"\x01"))
self.assertEqual(b[1], ord(b"\xe0"))
def test_16bit_s(self):
im = Image.open("Tests/images/16bit.s.tif")
im.load()
self.assertEqual(im.mode, "I")
self.assertEqual(im.getpixel((0, 0)), 32767)
self.assertEqual(im.getpixel((0, 1)), 0)
with Image.open("Tests/images/16bit.s.tif") as im:
im.load()
self.assertEqual(im.mode, "I")
self.assertEqual(im.getpixel((0, 0)), 32767)
self.assertEqual(im.getpixel((0, 1)), 0)
def test_12bit_rawmode(self):
""" Are we generating the same interpretation
of the image as Imagemagick is? """
im = Image.open("Tests/images/12bit.cropped.tif")
with Image.open("Tests/images/12bit.cropped.tif") as im:
# to make the target --
# convert 12bit.cropped.tif -depth 16 tmp.tif
# convert tmp.tif -evaluate RightShift 4 12in16bit2.tif
# imagemagick will auto scale so that a 12bit FFF is 16bit FFF0,
# so we need to unshift so that the integer values are the same.
# to make the target --
# convert 12bit.cropped.tif -depth 16 tmp.tif
# convert tmp.tif -evaluate RightShift 4 12in16bit2.tif
# imagemagick will auto scale so that a 12bit FFF is 16bit FFF0,
# so we need to unshift so that the integer values are the same.
self.assert_image_equal_tofile(im, "Tests/images/12in16bit.tif")
self.assert_image_equal_tofile(im, "Tests/images/12in16bit.tif")
def test_32bit_float(self):
# Issue 614, specific 32-bit float format
path = "Tests/images/10ct_32bit_128.tiff"
im = Image.open(path)
im.load()
with Image.open(path) as im:
im.load()
self.assertEqual(im.getpixel((0, 0)), -0.4526388943195343)
self.assertEqual(im.getextrema(), (-3.140936851501465, 3.140684127807617))
self.assertEqual(im.getpixel((0, 0)), -0.4526388943195343)
self.assertEqual(im.getextrema(), (-3.140936851501465, 3.140684127807617))
def test_unknown_pixel_mode(self):
self.assertRaises(
@ -300,10 +287,10 @@ class TestFileTiff(PillowTestCase):
self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 0, 255))
def test_multipage_last_frame(self):
im = Image.open("Tests/images/multipage-lastframe.tif")
im.load()
self.assertEqual(im.size, (20, 20))
self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 0, 255))
with Image.open("Tests/images/multipage-lastframe.tif") as im:
im.load()
self.assertEqual(im.size, (20, 20))
self.assertEqual(im.convert("RGB").getpixel((0, 0)), (0, 0, 255))
def test___str__(self):
filename = "Tests/images/pil136.tiff"
@ -419,10 +406,10 @@ class TestFileTiff(PillowTestCase):
def test_4bit(self):
test_file = "Tests/images/hopper_gray_4bpp.tif"
original = hopper("L")
im = Image.open(test_file)
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.mode, "L")
self.assert_image_similar(im, original, 7.3)
with Image.open(test_file) as im:
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.mode, "L")
self.assert_image_similar(im, original, 7.3)
def test_gray_semibyte_per_pixel(self):
test_files = (
@ -447,15 +434,15 @@ class TestFileTiff(PillowTestCase):
)
original = hopper("L")
for epsilon, group in test_files:
im = Image.open(group[0])
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.mode, "L")
self.assert_image_similar(im, original, epsilon)
for file in group[1:]:
im2 = Image.open(file)
self.assertEqual(im2.size, (128, 128))
self.assertEqual(im2.mode, "L")
self.assert_image_equal(im, im2)
with Image.open(group[0]) as im:
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.mode, "L")
self.assert_image_similar(im, original, epsilon)
for file in group[1:]:
with Image.open(file) as im2:
self.assertEqual(im2.size, (128, 128))
self.assertEqual(im2.mode, "L")
self.assert_image_equal(im, im2)
def test_with_underscores(self):
kwargs = {"resolution_unit": "inch", "x_resolution": 72, "y_resolution": 36}
@ -475,29 +462,26 @@ class TestFileTiff(PillowTestCase):
# Test an image of all '0' values
pixel_value = 0x1234
infile = "Tests/images/uint16_1_4660.tif"
im = Image.open(infile)
self.assertEqual(im.getpixel((0, 0)), pixel_value)
with Image.open(infile) as im:
self.assertEqual(im.getpixel((0, 0)), pixel_value)
tmpfile = self.tempfile("temp.tif")
im.save(tmpfile)
tmpfile = self.tempfile("temp.tif")
im.save(tmpfile)
reloaded = Image.open(tmpfile)
self.assert_image_equal(im, reloaded)
with Image.open(tmpfile) as reloaded:
self.assert_image_equal(im, reloaded)
def test_strip_raw(self):
infile = "Tests/images/tiff_strip_raw.tif"
im = Image.open(infile)
self.assert_image_equal_tofile(im, "Tests/images/tiff_adobe_deflate.png")
with Image.open(infile) as im:
self.assert_image_equal_tofile(im, "Tests/images/tiff_adobe_deflate.png")
def test_strip_planar_raw(self):
# gdal_translate -of GTiff -co INTERLEAVE=BAND \
# tiff_strip_raw.tif tiff_strip_planar_raw.tiff
infile = "Tests/images/tiff_strip_planar_raw.tif"
im = Image.open(infile)
self.assert_image_equal_tofile(im, "Tests/images/tiff_adobe_deflate.png")
with Image.open(infile) as im:
self.assert_image_equal_tofile(im, "Tests/images/tiff_adobe_deflate.png")
def test_strip_planar_raw_with_overviews(self):
# gdaladdo tiff_strip_planar_raw2.tif 2 4 8 16
@ -510,9 +494,8 @@ class TestFileTiff(PillowTestCase):
# -co BLOCKYSIZE=32 -co INTERLEAVE=BAND \
# tiff_tiled_raw.tif tiff_tiled_planar_raw.tiff
infile = "Tests/images/tiff_tiled_planar_raw.tif"
im = Image.open(infile)
self.assert_image_equal_tofile(im, "Tests/images/tiff_adobe_deflate.png")
with Image.open(infile) as im:
self.assert_image_equal_tofile(im, "Tests/images/tiff_adobe_deflate.png")
def test_palette(self):
for mode in ["P", "PA"]:
@ -521,8 +504,8 @@ class TestFileTiff(PillowTestCase):
im = hopper(mode)
im.save(outfile)
reloaded = Image.open(outfile)
self.assert_image_equal(im.convert("RGB"), reloaded.convert("RGB"))
with Image.open(outfile) as reloaded:
self.assert_image_equal(im.convert("RGB"), reloaded.convert("RGB"))
def test_tiff_save_all(self):
mp = BytesIO()
@ -540,20 +523,19 @@ class TestFileTiff(PillowTestCase):
im.copy().save(mp, format="TIFF", save_all=True, append_images=ims)
mp.seek(0, os.SEEK_SET)
reread = Image.open(mp)
self.assertEqual(reread.n_frames, 3)
with Image.open(mp) as reread:
self.assertEqual(reread.n_frames, 3)
# Test appending using a generator
def imGenerator(ims):
for im in ims:
yield im
yield from ims
mp = BytesIO()
im.save(mp, format="TIFF", save_all=True, append_images=imGenerator(ims))
mp.seek(0, os.SEEK_SET)
reread = Image.open(mp)
self.assertEqual(reread.n_frames, 3)
with Image.open(mp) as reread:
self.assertEqual(reread.n_frames, 3)
def test_saving_icc_profile(self):
# Tests saving TIFF with icc_profile set.

View File

@ -130,14 +130,13 @@ class TestFileTiffMetadata(PillowTestCase):
def test_write_metadata(self):
""" Test metadata writing through the python code """
img = Image.open("Tests/images/hopper.tif")
f = self.tempfile("temp.tiff")
img.save(f, tiffinfo=img.tag)
with Image.open(f) as loaded:
with Image.open("Tests/images/hopper.tif") as img:
f = self.tempfile("temp.tiff")
img.save(f, tiffinfo=img.tag)
original = img.tag_v2.named()
with Image.open(f) as loaded:
reloaded = loaded.tag_v2.named()
for k, v in original.items():
@ -161,13 +160,13 @@ class TestFileTiffMetadata(PillowTestCase):
self.assert_deep_equal(
original[tag],
value,
"%s didn't roundtrip, %s, %s" % (tag, original[tag], value),
"{} didn't roundtrip, {}, {}".format(tag, original[tag], value),
)
else:
self.assertEqual(
original[tag],
value,
"%s didn't roundtrip, %s, %s" % (tag, original[tag], value),
"{} didn't roundtrip, {}, {}".format(tag, original[tag], value),
)
for tag, value in original.items():
@ -187,10 +186,10 @@ class TestFileTiffMetadata(PillowTestCase):
def test_iccprofile(self):
# https://github.com/python-pillow/Pillow/issues/1462
im = Image.open("Tests/images/hopper.iccprofile.tif")
out = self.tempfile("temp.tiff")
with Image.open("Tests/images/hopper.iccprofile.tif") as im:
im.save(out)
im.save(out)
with Image.open(out) as reloaded:
self.assertNotIsInstance(im.info["icc_profile"], tuple)
self.assertEqual(im.info["icc_profile"], reloaded.info["icc_profile"])
@ -205,14 +204,14 @@ class TestFileTiffMetadata(PillowTestCase):
self.assertTrue(im.info["icc_profile"])
def test_iccprofile_save_png(self):
im = Image.open("Tests/images/hopper.iccprofile.tif")
outfile = self.tempfile("temp.png")
im.save(outfile)
with Image.open("Tests/images/hopper.iccprofile.tif") as im:
outfile = self.tempfile("temp.png")
im.save(outfile)
def test_iccprofile_binary_save_png(self):
im = Image.open("Tests/images/hopper.iccprofile_binary.tif")
outfile = self.tempfile("temp.png")
im.save(outfile)
with Image.open("Tests/images/hopper.iccprofile_binary.tif") as im:
outfile = self.tempfile("temp.png")
im.save(outfile)
def test_exif_div_zero(self):
im = hopper()
@ -241,12 +240,11 @@ class TestFileTiffMetadata(PillowTestCase):
self.assertIn(33432, info)
def test_PhotoshopInfo(self):
im = Image.open("Tests/images/issue_2278.tif")
self.assertEqual(len(im.tag_v2[34377]), 1)
self.assertIsInstance(im.tag_v2[34377][0], bytes)
out = self.tempfile("temp.tiff")
im.save(out)
with Image.open("Tests/images/issue_2278.tif") as im:
self.assertEqual(len(im.tag_v2[34377]), 1)
self.assertIsInstance(im.tag_v2[34377][0], bytes)
out = self.tempfile("temp.tiff")
im.save(out)
with Image.open(out) as reloaded:
self.assertEqual(len(reloaded.tag_v2[34377]), 1)
self.assertIsInstance(reloaded.tag_v2[34377][0], bytes)

View File

@ -1,6 +1,8 @@
import unittest
from PIL import Image, WebPImagePlugin
from .helper import PillowTestCase, hopper, unittest
from .helper import PillowTestCase, hopper
try:
from PIL import _webp
@ -39,19 +41,18 @@ class TestFileWebp(PillowTestCase):
Does it have the bits we expect?
"""
image = Image.open("Tests/images/hopper.webp")
with Image.open("Tests/images/hopper.webp") as image:
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
# generated with:
# dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm
self.assert_image_similar_tofile(
image, "Tests/images/hopper_webp_bits.ppm", 1.0
)
# generated with:
# dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm
self.assert_image_similar_tofile(
image, "Tests/images/hopper_webp_bits.ppm", 1.0
)
def test_write_rgb(self):
"""
@ -62,26 +63,25 @@ class TestFileWebp(PillowTestCase):
temp_file = self.tempfile("temp.webp")
hopper(self.rgb_mode).save(temp_file)
image = Image.open(temp_file)
with Image.open(temp_file) as image:
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
# generated with: dwebp -ppm temp.webp -o hopper_webp_write.ppm
self.assert_image_similar_tofile(
image, "Tests/images/hopper_webp_write.ppm", 12.0
)
# generated with: dwebp -ppm temp.webp -o hopper_webp_write.ppm
self.assert_image_similar_tofile(
image, "Tests/images/hopper_webp_write.ppm", 12.0
)
# This test asserts that the images are similar. If the average pixel
# difference between the two images is less than the epsilon value,
# then we're going to accept that it's a reasonable lossy version of
# the image. The old lena images for WebP are showing ~16 on
# Ubuntu, the jpegs are showing ~18.
target = hopper(self.rgb_mode)
self.assert_image_similar(image, target, 12.0)
# This test asserts that the images are similar. If the average pixel
# difference between the two images is less than the epsilon value,
# then we're going to accept that it's a reasonable lossy version of
# the image. The old lena images for WebP are showing ~16 on
# Ubuntu, the jpegs are showing ~18.
target = hopper(self.rgb_mode)
self.assert_image_similar(image, target, 12.0)
def test_write_unsupported_mode_L(self):
"""
@ -91,17 +91,16 @@ class TestFileWebp(PillowTestCase):
temp_file = self.tempfile("temp.webp")
hopper("L").save(temp_file)
image = Image.open(temp_file)
with Image.open(temp_file) as image:
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
self.assertEqual(image.format, "WEBP")
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
target = hopper("L").convert(self.rgb_mode)
image.load()
image.getdata()
target = hopper("L").convert(self.rgb_mode)
self.assert_image_similar(image, target, 10.0)
self.assert_image_similar(image, target, 10.0)
def test_write_unsupported_mode_P(self):
"""
@ -111,17 +110,16 @@ class TestFileWebp(PillowTestCase):
temp_file = self.tempfile("temp.webp")
hopper("P").save(temp_file)
image = Image.open(temp_file)
with Image.open(temp_file) as image:
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
self.assertEqual(image.format, "WEBP")
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
target = hopper("P").convert(self.rgb_mode)
image.load()
image.getdata()
target = hopper("P").convert(self.rgb_mode)
self.assert_image_similar(image, target, 50.0)
self.assert_image_similar(image, target, 50.0)
def test_WebPEncode_with_invalid_args(self):
"""
@ -143,10 +141,9 @@ class TestFileWebp(PillowTestCase):
def test_no_resource_warning(self):
file_path = "Tests/images/hopper.webp"
image = Image.open(file_path)
temp_file = self.tempfile("temp.webp")
self.assert_warning(None, image.save, temp_file)
with Image.open(file_path) as image:
temp_file = self.tempfile("temp.webp")
self.assert_warning(None, image.save, temp_file)
def test_file_pointer_could_be_reused(self):
file_path = "Tests/images/hopper.webp"

View File

@ -1,6 +1,8 @@
import unittest
from PIL import Image
from .helper import PillowTestCase, hopper, unittest
from .helper import PillowTestCase, hopper
try:
from PIL import _webp
@ -24,18 +26,17 @@ class TestFileWebpAlpha(PillowTestCase):
# Generated with `cwebp transparent.png -o transparent.webp`
file_path = "Tests/images/transparent.webp"
image = Image.open(file_path)
with Image.open(file_path) as image:
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, (200, 150))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, (200, 150))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
image.tobytes()
image.tobytes()
target = Image.open("Tests/images/transparent.png")
self.assert_image_similar(image, target, 20.0)
with Image.open("Tests/images/transparent.png") as target:
self.assert_image_similar(image, target, 20.0)
def test_write_lossless_rgb(self):
"""
@ -54,16 +55,16 @@ class TestFileWebpAlpha(PillowTestCase):
pil_image.save(temp_file, lossless=True)
image = Image.open(temp_file)
image.load()
with Image.open(temp_file) as image:
image.load()
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, pil_image.size)
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, pil_image.size)
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
self.assert_image_equal(image, pil_image)
self.assert_image_equal(image, pil_image)
def test_write_rgba(self):
"""
@ -79,21 +80,21 @@ class TestFileWebpAlpha(PillowTestCase):
if _webp.WebPDecoderBuggyAlpha(self):
return
image = Image.open(temp_file)
image.load()
with Image.open(temp_file) as image:
image.load()
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, (10, 10))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, (10, 10))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
# early versions of webp are known to produce higher deviations:
# deal with it
if _webp.WebPDecoderVersion(self) <= 0x201:
self.assert_image_similar(image, pil_image, 3.0)
else:
self.assert_image_similar(image, pil_image, 1.0)
# early versions of webp are known to produce higher deviations:
# deal with it
if _webp.WebPDecoderVersion(self) <= 0x201:
self.assert_image_similar(image, pil_image, 3.0)
else:
self.assert_image_similar(image, pil_image, 1.0)
def test_write_unsupported_mode_PA(self):
"""
@ -105,15 +106,14 @@ class TestFileWebpAlpha(PillowTestCase):
file_path = "Tests/images/transparent.gif"
with Image.open(file_path) as im:
im.save(temp_file)
image = Image.open(temp_file)
with Image.open(temp_file) as image:
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, (200, 150))
self.assertEqual(image.format, "WEBP")
self.assertEqual(image.mode, "RGBA")
self.assertEqual(image.size, (200, 150))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
with Image.open(file_path) as im:
target = im.convert("RGBA")
image.load()
image.getdata()
with Image.open(file_path) as im:
target = im.convert("RGBA")
self.assert_image_similar(image, target, 25.0)
self.assert_image_similar(image, target, 25.0)

View File

@ -48,18 +48,18 @@ class TestFileWebpAnimation(PillowTestCase):
temp_file = self.tempfile("temp.webp")
orig.save(temp_file, save_all=True)
im = Image.open(temp_file)
self.assertEqual(im.n_frames, orig.n_frames)
with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, orig.n_frames)
# Compare first and last frames to the original animated GIF
orig.load()
im.load()
self.assert_image_similar(im, orig.convert("RGBA"), 25.0)
orig.seek(orig.n_frames - 1)
im.seek(im.n_frames - 1)
orig.load()
im.load()
self.assert_image_similar(im, orig.convert("RGBA"), 25.0)
# Compare first and last frames to the original animated GIF
orig.load()
im.load()
self.assert_image_similar(im, orig.convert("RGBA"), 25.0)
orig.seek(orig.n_frames - 1)
im.seek(im.n_frames - 1)
orig.load()
im.load()
self.assert_image_similar(im, orig.convert("RGBA"), 25.0)
def test_write_animation_RGB(self):
"""
@ -68,40 +68,38 @@ class TestFileWebpAnimation(PillowTestCase):
"""
def check(temp_file):
im = Image.open(temp_file)
self.assertEqual(im.n_frames, 2)
with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, 2)
# Compare first frame to original
im.load()
self.assert_image_equal(im, frame1.convert("RGBA"))
# Compare first frame to original
im.load()
self.assert_image_equal(im, frame1.convert("RGBA"))
# Compare second frame to original
im.seek(1)
im.load()
self.assert_image_equal(im, frame2.convert("RGBA"))
# Compare second frame to original
im.seek(1)
im.load()
self.assert_image_equal(im, frame2.convert("RGBA"))
frame1 = Image.open("Tests/images/anim_frame1.webp")
frame2 = Image.open("Tests/images/anim_frame2.webp")
with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2:
temp_file1 = self.tempfile("temp.webp")
frame1.copy().save(
temp_file1, save_all=True, append_images=[frame2], lossless=True
)
check(temp_file1)
temp_file1 = self.tempfile("temp.webp")
frame1.copy().save(
temp_file1, save_all=True, append_images=[frame2], lossless=True
)
check(temp_file1)
# Tests appending using a generator
def imGenerator(ims):
yield from ims
# Tests appending using a generator
def imGenerator(ims):
for im in ims:
yield im
temp_file2 = self.tempfile("temp_generator.webp")
frame1.copy().save(
temp_file2,
save_all=True,
append_images=imGenerator([frame2]),
lossless=True,
)
check(temp_file2)
temp_file2 = self.tempfile("temp_generator.webp")
frame1.copy().save(
temp_file2,
save_all=True,
append_images=imGenerator([frame2]),
lossless=True,
)
check(temp_file2)
def test_timestamp_and_duration(self):
"""
@ -111,27 +109,27 @@ class TestFileWebpAnimation(PillowTestCase):
durations = [0, 10, 20, 30, 40]
temp_file = self.tempfile("temp.webp")
frame1 = Image.open("Tests/images/anim_frame1.webp")
frame2 = Image.open("Tests/images/anim_frame2.webp")
frame1.save(
temp_file,
save_all=True,
append_images=[frame2, frame1, frame2, frame1],
duration=durations,
)
with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2:
frame1.save(
temp_file,
save_all=True,
append_images=[frame2, frame1, frame2, frame1],
duration=durations,
)
im = Image.open(temp_file)
self.assertEqual(im.n_frames, 5)
self.assertTrue(im.is_animated)
with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, 5)
self.assertTrue(im.is_animated)
# Check that timestamps and durations match original values specified
ts = 0
for frame in range(im.n_frames):
im.seek(frame)
im.load()
self.assertEqual(im.info["duration"], durations[frame])
self.assertEqual(im.info["timestamp"], ts)
ts += durations[frame]
# Check that timestamps and durations match original values specified
ts = 0
for frame in range(im.n_frames):
im.seek(frame)
im.load()
self.assertEqual(im.info["duration"], durations[frame])
self.assertEqual(im.info["timestamp"], ts)
ts += durations[frame]
def test_seeking(self):
"""
@ -142,24 +140,24 @@ class TestFileWebpAnimation(PillowTestCase):
dur = 33
temp_file = self.tempfile("temp.webp")
frame1 = Image.open("Tests/images/anim_frame1.webp")
frame2 = Image.open("Tests/images/anim_frame2.webp")
frame1.save(
temp_file,
save_all=True,
append_images=[frame2, frame1, frame2, frame1],
duration=dur,
)
with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2:
frame1.save(
temp_file,
save_all=True,
append_images=[frame2, frame1, frame2, frame1],
duration=dur,
)
im = Image.open(temp_file)
self.assertEqual(im.n_frames, 5)
self.assertTrue(im.is_animated)
with Image.open(temp_file) as im:
self.assertEqual(im.n_frames, 5)
self.assertTrue(im.is_animated)
# Traverse frames in reverse, checking timestamps and durations
ts = dur * (im.n_frames - 1)
for frame in reversed(range(im.n_frames)):
im.seek(frame)
im.load()
self.assertEqual(im.info["duration"], dur)
self.assertEqual(im.info["timestamp"], ts)
ts -= dur
# Traverse frames in reverse, checking timestamps and durations
ts = dur * (im.n_frames - 1)
for frame in reversed(range(im.n_frames)):
im.seek(frame)
im.load()
self.assertEqual(im.info["duration"], dur)
self.assertEqual(im.info["timestamp"], ts)
ts -= dur

View File

@ -26,13 +26,13 @@ class TestFileWebpLossless(PillowTestCase):
hopper(self.rgb_mode).save(temp_file, lossless=True)
image = Image.open(temp_file)
image.load()
with Image.open(temp_file) as image:
image.load()
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
self.assertEqual(image.mode, self.rgb_mode)
self.assertEqual(image.size, (128, 128))
self.assertEqual(image.format, "WEBP")
image.load()
image.getdata()
self.assert_image_equal(image, hopper(self.rgb_mode))
self.assert_image_equal(image, hopper(self.rgb_mode))

View File

@ -42,17 +42,15 @@ class TestFileWebpMetadata(PillowTestCase):
def test_write_exif_metadata(self):
file_path = "Tests/images/flower.jpg"
image = Image.open(file_path)
expected_exif = image.info["exif"]
test_buffer = BytesIO()
with Image.open(file_path) as image:
expected_exif = image.info["exif"]
image.save(test_buffer, "webp", exif=expected_exif)
image.save(test_buffer, "webp", exif=expected_exif)
test_buffer.seek(0)
webp_image = Image.open(test_buffer)
webp_exif = webp_image.info.get("exif", None)
with Image.open(test_buffer) as webp_image:
webp_exif = webp_image.info.get("exif", None)
self.assertTrue(webp_exif)
if webp_exif:
self.assertEqual(webp_exif, expected_exif, "WebP EXIF didn't match")
@ -74,17 +72,15 @@ class TestFileWebpMetadata(PillowTestCase):
def test_write_icc_metadata(self):
file_path = "Tests/images/flower2.jpg"
image = Image.open(file_path)
expected_icc_profile = image.info["icc_profile"]
test_buffer = BytesIO()
with Image.open(file_path) as image:
expected_icc_profile = image.info["icc_profile"]
image.save(test_buffer, "webp", icc_profile=expected_icc_profile)
image.save(test_buffer, "webp", icc_profile=expected_icc_profile)
test_buffer.seek(0)
webp_image = Image.open(test_buffer)
webp_icc_profile = webp_image.info.get("icc_profile", None)
with Image.open(test_buffer) as webp_image:
webp_icc_profile = webp_image.info.get("icc_profile", None)
self.assertTrue(webp_icc_profile)
if webp_icc_profile:
@ -94,37 +90,35 @@ class TestFileWebpMetadata(PillowTestCase):
def test_read_no_exif(self):
file_path = "Tests/images/flower.jpg"
image = Image.open(file_path)
self.assertIn("exif", image.info)
test_buffer = BytesIO()
with Image.open(file_path) as image:
self.assertIn("exif", image.info)
image.save(test_buffer, "webp")
image.save(test_buffer, "webp")
test_buffer.seek(0)
webp_image = Image.open(test_buffer)
self.assertFalse(webp_image._getexif())
with Image.open(test_buffer) as webp_image:
self.assertFalse(webp_image._getexif())
def test_write_animated_metadata(self):
if not _webp.HAVE_WEBPANIM:
self.skipTest("WebP animation support not available")
iccp_data = "<iccp_data>".encode("utf-8")
exif_data = "<exif_data>".encode("utf-8")
xmp_data = "<xmp_data>".encode("utf-8")
iccp_data = b"<iccp_data>"
exif_data = b"<exif_data>"
xmp_data = b"<xmp_data>"
temp_file = self.tempfile("temp.webp")
frame1 = Image.open("Tests/images/anim_frame1.webp")
frame2 = Image.open("Tests/images/anim_frame2.webp")
frame1.save(
temp_file,
save_all=True,
append_images=[frame2, frame1, frame2],
icc_profile=iccp_data,
exif=exif_data,
xmp=xmp_data,
)
with Image.open("Tests/images/anim_frame1.webp") as frame1:
with Image.open("Tests/images/anim_frame2.webp") as frame2:
frame1.save(
temp_file,
save_all=True,
append_images=[frame2, frame1, frame2],
icc_profile=iccp_data,
exif=exif_data,
xmp=xmp_data,
)
with Image.open(temp_file) as image:
self.assertIn("icc_profile", image.info)

View File

@ -12,9 +12,9 @@ class TestFileWmf(PillowTestCase):
# Currently, support for WMF/EMF is Windows-only
im.load()
# Compare to reference rendering
imref = Image.open("Tests/images/drawing_emf_ref.png")
imref.load()
self.assert_image_similar(im, imref, 0)
with Image.open("Tests/images/drawing_emf_ref.png") as imref:
imref.load()
self.assert_image_similar(im, imref, 0)
# Test basic WMF open and rendering
with Image.open("Tests/images/drawing.wmf") as im:
@ -22,9 +22,9 @@ class TestFileWmf(PillowTestCase):
# Currently, support for WMF/EMF is Windows-only
im.load()
# Compare to reference rendering
imref = Image.open("Tests/images/drawing_wmf_ref.png")
imref.load()
self.assert_image_similar(im, imref, 2.0)
with Image.open("Tests/images/drawing_wmf_ref.png") as imref:
imref.load()
self.assert_image_similar(im, imref, 2.0)
def test_register_handler(self):
class TestHandler:

View File

@ -30,11 +30,10 @@ static char basic_bits[] = {
class TestFileXbm(PillowTestCase):
def test_pil151(self):
im = Image.open(BytesIO(PIL151))
im.load()
self.assertEqual(im.mode, "1")
self.assertEqual(im.size, (32, 32))
with Image.open(BytesIO(PIL151)) as im:
im.load()
self.assertEqual(im.mode, "1")
self.assertEqual(im.size, (32, 32))
def test_open(self):
# Arrange

View File

@ -7,14 +7,14 @@ TEST_FILE = "Tests/images/hopper.xpm"
class TestFileXpm(PillowTestCase):
def test_sanity(self):
im = Image.open(TEST_FILE)
im.load()
self.assertEqual(im.mode, "P")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "XPM")
with Image.open(TEST_FILE) as im:
im.load()
self.assertEqual(im.mode, "P")
self.assertEqual(im.size, (128, 128))
self.assertEqual(im.format, "XPM")
# large error due to quantization->44 colors.
self.assert_image_similar(im.convert("RGB"), hopper("RGB"), 60)
# large error due to quantization->44 colors.
self.assert_image_similar(im.convert("RGB"), hopper("RGB"), 60)
def test_invalid_file(self):
invalid_file = "Tests/images/flower.jpg"

View File

@ -8,14 +8,14 @@ TEST_FILE = "Tests/images/hopper.p7"
class TestFileXVThumb(PillowTestCase):
def test_open(self):
# Act
im = Image.open(TEST_FILE)
with Image.open(TEST_FILE) as im:
# Assert
self.assertEqual(im.format, "XVThumb")
# Assert
self.assertEqual(im.format, "XVThumb")
# Create a Hopper image with a similar XV palette
im_hopper = hopper().quantize(palette=im)
self.assert_image_similar(im, im_hopper, 9)
# Create a Hopper image with a similar XV palette
im_hopper = hopper().quantize(palette=im)
self.assert_image_similar(im, im_hopper, 9)
def test_unexpected_eof(self):
# Test unexpected EOF reading XV thumbnail file

View File

@ -1,8 +1,8 @@
from __future__ import division
import unittest
from PIL import Image, ImageDraw, ImageFont, features
from .helper import PillowLeakTestCase, is_win32, unittest
from .helper import PillowLeakTestCase, is_win32
@unittest.skipIf(is_win32(), "requires Unix or macOS")

View File

@ -1,5 +1,4 @@
from PIL import FontFile, Image, ImageDraw, ImageFont, PcfFontFile
from PIL._util import py3
from .helper import PillowTestCase
@ -74,6 +73,5 @@ class TestFontPcf(PillowTestCase):
def test_high_characters(self):
message = "".join(chr(i + 1) for i in range(140, 232))
self._test_high_characters(message)
# accept bytes instances in Py3.
if py3:
self._test_high_characters(message.encode("latin1"))
# accept bytes instances.
self._test_high_characters(message.encode("latin1"))

View File

@ -2,7 +2,6 @@ import colorsys
import itertools
from PIL import Image
from PIL._util import py3
from .helper import PillowTestCase, hopper
@ -49,27 +48,18 @@ class TestFormatHSV(PillowTestCase):
(r, g, b) = im.split()
if py3:
conv_func = self.int_to_float
else:
conv_func = self.str_to_float
if hasattr(itertools, "izip"):
iter_helper = itertools.izip
else:
iter_helper = itertools.zip_longest
conv_func = self.int_to_float
converted = [
self.tuple_to_ints(func(conv_func(_r), conv_func(_g), conv_func(_b)))
for (_r, _g, _b) in iter_helper(r.tobytes(), g.tobytes(), b.tobytes())
for (_r, _g, _b) in itertools.zip_longest(
r.tobytes(), g.tobytes(), b.tobytes()
)
]
if py3:
new_bytes = b"".join(
bytes(chr(h) + chr(s) + chr(v), "latin-1") for (h, s, v) in converted
)
else:
new_bytes = b"".join(chr(h) + chr(s) + chr(v) for (h, s, v) in converted)
new_bytes = b"".join(
bytes(chr(h) + chr(s) + chr(v), "latin-1") for (h, s, v) in converted
)
hsv = Image.frombytes(mode, r.size, new_bytes)

View File

@ -5,21 +5,21 @@ from .helper import PillowTestCase
class TestFormatLab(PillowTestCase):
def test_white(self):
i = Image.open("Tests/images/lab.tif")
with Image.open("Tests/images/lab.tif") as i:
i.load()
i.load()
self.assertEqual(i.mode, "LAB")
self.assertEqual(i.mode, "LAB")
self.assertEqual(i.getbands(), ("L", "A", "B"))
self.assertEqual(i.getbands(), ("L", "A", "B"))
k = i.getpixel((0, 0))
L = i.getdata(0)
a = i.getdata(1)
b = i.getdata(2)
k = i.getpixel((0, 0))
self.assertEqual(k, (255, 128, 128))
L = i.getdata(0)
a = i.getdata(1)
b = i.getdata(2)
self.assertEqual(list(L), [255] * 100)
self.assertEqual(list(a), [128] * 100)
self.assertEqual(list(b), [128] * 100)
@ -27,15 +27,13 @@ class TestFormatLab(PillowTestCase):
def test_green(self):
# l= 50 (/100), a = -100 (-128 .. 128) b=0 in PS
# == RGB: 0, 152, 117
i = Image.open("Tests/images/lab-green.tif")
k = i.getpixel((0, 0))
with Image.open("Tests/images/lab-green.tif") as i:
k = i.getpixel((0, 0))
self.assertEqual(k, (128, 28, 128))
def test_red(self):
# l= 50 (/100), a = 100 (-128 .. 128) b=0 in PS
# == RGB: 255, 0, 124
i = Image.open("Tests/images/lab-red.tif")
k = i.getpixel((0, 0))
with Image.open("Tests/images/lab-red.tif") as i:
k = i.getpixel((0, 0))
self.assertEqual(k, (128, 228, 128))

View File

@ -1,11 +1,11 @@
import os
import shutil
import tempfile
import unittest
from PIL import Image
from PIL._util import py3
from PIL import Image, UnidentifiedImageError
from .helper import PillowTestCase, hopper, is_win32, unittest
from .helper import PillowTestCase, hopper, is_win32
class TestImage(PillowTestCase):
@ -48,6 +48,9 @@ class TestImage(PillowTestCase):
Image.new(mode, (1, 1))
self.assertEqual(str(e.exception), "unrecognized image mode")
def test_exception_inheritance(self):
self.assertTrue(issubclass(UnidentifiedImageError, IOError))
def test_sanity(self):
im = Image.new("L", (100, 100))
@ -80,20 +83,14 @@ class TestImage(PillowTestCase):
im.size = (3, 4)
def test_invalid_image(self):
if py3:
import io
import io
im = io.BytesIO(b"")
else:
import StringIO
im = StringIO.StringIO("")
self.assertRaises(IOError, Image.open, im)
im = io.BytesIO(b"")
self.assertRaises(UnidentifiedImageError, Image.open, im)
def test_bad_mode(self):
self.assertRaises(ValueError, Image.open, "filename", "bad mode")
@unittest.skipUnless(Image.HAS_PATHLIB, "requires pathlib/pathlib2")
def test_pathlib(self):
from PIL.Image import Path
@ -101,19 +98,19 @@ class TestImage(PillowTestCase):
self.assertEqual(im.mode, "P")
self.assertEqual(im.size, (10, 10))
im = Image.open(Path("Tests/images/hopper.jpg"))
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
with Image.open(Path("Tests/images/hopper.jpg")) as im:
self.assertEqual(im.mode, "RGB")
self.assertEqual(im.size, (128, 128))
temp_file = self.tempfile("temp.jpg")
if os.path.exists(temp_file):
os.remove(temp_file)
im.save(Path(temp_file))
temp_file = self.tempfile("temp.jpg")
if os.path.exists(temp_file):
os.remove(temp_file)
im.save(Path(temp_file))
def test_fp_name(self):
temp_file = self.tempfile("temp.jpg")
class FP(object):
class FP:
def write(a, b):
pass
@ -130,8 +127,8 @@ class TestImage(PillowTestCase):
with tempfile.TemporaryFile() as fp:
im.save(fp, "JPEG")
fp.seek(0)
reloaded = Image.open(fp)
self.assert_image_similar(im, reloaded, 20)
with Image.open(fp) as reloaded:
self.assert_image_similar(im, reloaded, 20)
def test_unknown_extension(self):
im = hopper()
@ -153,9 +150,9 @@ class TestImage(PillowTestCase):
temp_file = self.tempfile("temp.bmp")
shutil.copy("Tests/images/rgb32bf-rgba.bmp", temp_file)
im = Image.open(temp_file)
self.assertTrue(im.readonly)
im.save(temp_file)
with Image.open(temp_file) as im:
self.assertTrue(im.readonly)
im.save(temp_file)
def test_dump(self):
im = Image.new("L", (10, 10))
@ -368,8 +365,8 @@ class TestImage(PillowTestCase):
# Assert
self.assertEqual(im.size, (512, 512))
im2 = Image.open("Tests/images/effect_mandelbrot.png")
self.assert_image_equal(im, im2)
with Image.open("Tests/images/effect_mandelbrot.png") as im2:
self.assert_image_equal(im, im2)
def test_effect_mandelbrot_bad_arguments(self):
# Arrange
@ -410,8 +407,8 @@ class TestImage(PillowTestCase):
# Assert
self.assertEqual(im.size, (128, 128))
im3 = Image.open("Tests/images/effect_spread.png")
self.assert_image_similar(im2, im3, 110)
with Image.open("Tests/images/effect_spread.png") as im3:
self.assert_image_similar(im2, im3, 110)
def test_check_size(self):
# Checking that the _check_size function throws value errors
@ -478,7 +475,8 @@ class TestImage(PillowTestCase):
self.assertEqual(im.mode, mode)
self.assertEqual(im.getpixel((0, 0)), 0)
self.assertEqual(im.getpixel((255, 255)), 255)
target = Image.open(target_file).convert(mode)
with Image.open(target_file) as target:
target = target.convert(mode)
self.assert_image_equal(im, target)
def test_radial_gradient_wrong_mode(self):
@ -502,7 +500,8 @@ class TestImage(PillowTestCase):
self.assertEqual(im.mode, mode)
self.assertEqual(im.getpixel((0, 0)), 255)
self.assertEqual(im.getpixel((128, 128)), 0)
target = Image.open(target_file).convert(mode)
with Image.open(target_file) as target:
target = target.convert(mode)
self.assert_image_equal(im, target)
def test_register_extensions(self):
@ -592,11 +591,11 @@ class TestImage(PillowTestCase):
try:
im.load()
self.assertFail()
except IOError as e:
except OSError as e:
self.assertEqual(str(e), "buffer overrun when reading image file")
class MockEncoder(object):
class MockEncoder:
pass

View File

@ -2,11 +2,12 @@ import ctypes
import os
import subprocess
import sys
import unittest
from distutils import ccompiler, sysconfig
from PIL import Image
from .helper import PillowTestCase, hopper, is_win32, on_ci, unittest
from .helper import PillowTestCase, hopper, is_win32, on_ci
# CFFI imports pycparser which doesn't support PYTHONOPTIMIZE=2
# https://github.com/eliben/pycparser/pull/198#issuecomment-317001670
@ -125,7 +126,7 @@ class TestImageGetPixel(AccessTest):
self.assertEqual(
im.getpixel((0, 0)),
c,
"put/getpixel roundtrip failed for mode %s, color %s" % (mode, c),
"put/getpixel roundtrip failed for mode {}, color {}".format(mode, c),
)
# check putpixel negative index
@ -154,7 +155,7 @@ class TestImageGetPixel(AccessTest):
self.assertEqual(
im.getpixel((0, 0)),
c,
"initial color failed for mode %s, color %s " % (mode, c),
"initial color failed for mode {}, color {} ".format(mode, c),
)
# check initial color negative index
self.assertEqual(
@ -348,12 +349,8 @@ class TestEmbeddable(unittest.TestCase):
int main(int argc, char* argv[])
{
char *home = "%s";
#if PY_MAJOR_VERSION >= 3
wchar_t *whome = Py_DecodeLocale(home, NULL);
Py_SetPythonHome(whome);
#else
Py_SetPythonHome(home);
#endif
Py_InitializeEx(0);
Py_DECREF(PyImport_ImportModule("PIL.Image"));
@ -363,9 +360,7 @@ int main(int argc, char* argv[])
Py_DECREF(PyImport_ImportModule("PIL.Image"));
Py_Finalize();
#if PY_MAJOR_VERSION >= 3
PyMem_RawFree(whome);
#endif
return 0;
}

View File

@ -25,7 +25,7 @@ class TestImageArray(PillowTestCase):
self.assertEqual(test("RGBX"), (3, (100, 128, 4), "|u1", 51200))
def test_fromarray(self):
class Wrapper(object):
class Wrapper:
""" Class with API matching Image.fromarray """
def __init__(self, img, arr_params):
@ -52,3 +52,8 @@ class TestImageArray(PillowTestCase):
self.assertEqual(test("RGB"), ("RGB", (128, 100), True))
self.assertEqual(test("RGBA"), ("RGBA", (128, 100), True))
self.assertEqual(test("RGBX"), ("RGBA", (128, 100), True))
# Test mode is None with no "typestr" in the array interface
with self.assertRaises(TypeError):
wrapped = Wrapper(test("L"), {"shape": (100, 128)})
Image.fromarray(wrapped)

View File

@ -53,16 +53,16 @@ class TestImageConvert(PillowTestCase):
self.assertEqual(orig, converted)
def test_8bit(self):
im = Image.open("Tests/images/hopper.jpg")
self._test_float_conversion(im.convert("L"))
with Image.open("Tests/images/hopper.jpg") as im:
self._test_float_conversion(im.convert("L"))
def test_16bit(self):
im = Image.open("Tests/images/16bit.cropped.tif")
self._test_float_conversion(im)
with Image.open("Tests/images/16bit.cropped.tif") as im:
self._test_float_conversion(im)
def test_16bit_workaround(self):
im = Image.open("Tests/images/16bit.cropped.tif")
self._test_float_conversion(im.convert("I"))
with Image.open("Tests/images/16bit.cropped.tif") as im:
self._test_float_conversion(im.convert("I"))
def test_rgba_p(self):
im = hopper("RGBA")
@ -210,13 +210,13 @@ class TestImageConvert(PillowTestCase):
# Assert
self.assertEqual(converted_im.mode, mode)
self.assertEqual(converted_im.size, im.size)
target = Image.open("Tests/images/hopper-XYZ.png")
if converted_im.mode == "RGB":
self.assert_image_similar(converted_im, target, 3)
self.assertEqual(converted_im.info["transparency"], (105, 54, 4))
else:
self.assert_image_similar(converted_im, target.getchannel(0), 1)
self.assertEqual(converted_im.info["transparency"], 105)
with Image.open("Tests/images/hopper-XYZ.png") as target:
if converted_im.mode == "RGB":
self.assert_image_similar(converted_im, target, 3)
self.assertEqual(converted_im.info["transparency"], (105, 54, 4))
else:
self.assert_image_similar(converted_im, target.getchannel(0), 1)
self.assertEqual(converted_im.info["transparency"], 105)
matrix_convert("RGB")
matrix_convert("L")

View File

@ -76,13 +76,13 @@ class TestImageCrop(PillowTestCase):
test_img = "Tests/images/bmp/g/pal8-0.bmp"
extents = (1, 1, 10, 10)
# works prepatch
img = Image.open(test_img)
img2 = img.crop(extents)
with Image.open(test_img) as img:
img2 = img.crop(extents)
img2.load()
# fail prepatch
img = Image.open(test_img)
img = img.crop(extents)
with Image.open(test_img) as img:
img = img.crop(extents)
img.load()
def test_crop_zero(self):

View File

@ -99,45 +99,45 @@ class TestImageFilter(PillowTestCase):
self.assertRaises(ValueError, lambda: ImageFilter.Kernel((3, 3), (0, 0)))
def test_consistency_3x3(self):
source = Image.open("Tests/images/hopper.bmp")
reference = Image.open("Tests/images/hopper_emboss.bmp")
kernel = ImageFilter.Kernel( # noqa: E127
(3, 3),
# fmt: off
(-1, -1, 0,
-1, 0, 1,
0, 1, 1),
# fmt: on
0.3,
)
source = source.split() * 2
reference = reference.split() * 2
with Image.open("Tests/images/hopper.bmp") as source:
with Image.open("Tests/images/hopper_emboss.bmp") as reference:
kernel = ImageFilter.Kernel( # noqa: E127
(3, 3),
# fmt: off
(-1, -1, 0,
-1, 0, 1,
0, 1, 1),
# fmt: on
0.3,
)
source = source.split() * 2
reference = reference.split() * 2
for mode in ["L", "LA", "RGB", "CMYK"]:
self.assert_image_equal(
Image.merge(mode, source[: len(mode)]).filter(kernel),
Image.merge(mode, reference[: len(mode)]),
)
for mode in ["L", "LA", "RGB", "CMYK"]:
self.assert_image_equal(
Image.merge(mode, source[: len(mode)]).filter(kernel),
Image.merge(mode, reference[: len(mode)]),
)
def test_consistency_5x5(self):
source = Image.open("Tests/images/hopper.bmp")
reference = Image.open("Tests/images/hopper_emboss_more.bmp")
kernel = ImageFilter.Kernel( # noqa: E127
(5, 5),
# fmt: off
(-1, -1, -1, -1, 0,
-1, -1, -1, 0, 1,
-1, -1, 0, 1, 1,
-1, 0, 1, 1, 1,
0, 1, 1, 1, 1),
# fmt: on
0.3,
)
source = source.split() * 2
reference = reference.split() * 2
with Image.open("Tests/images/hopper.bmp") as source:
with Image.open("Tests/images/hopper_emboss_more.bmp") as reference:
kernel = ImageFilter.Kernel( # noqa: E127
(5, 5),
# fmt: off
(-1, -1, -1, -1, 0,
-1, -1, -1, 0, 1,
-1, -1, 0, 1, 1,
-1, 0, 1, 1, 1,
0, 1, 1, 1, 1),
# fmt: on
0.3,
)
source = source.split() * 2
reference = reference.split() * 2
for mode in ["L", "LA", "RGB", "CMYK"]:
self.assert_image_equal(
Image.merge(mode, source[: len(mode)]).filter(kernel),
Image.merge(mode, reference[: len(mode)]),
)
for mode in ["L", "LA", "RGB", "CMYK"]:
self.assert_image_equal(
Image.merge(mode, source[: len(mode)]).filter(kernel),
Image.merge(mode, reference[: len(mode)]),
)

View File

@ -6,7 +6,7 @@ from .test_imageqt import PillowQtTestCase
class TestFromQImage(PillowQtTestCase, PillowTestCase):
def setUp(self):
super(TestFromQImage, self).setUp()
super().setUp()
self.files_to_test = [
hopper(),
Image.open("Tests/images/transparent.png"),

View File

@ -19,7 +19,7 @@ class TestImageGetExtrema(PillowTestCase):
self.assertEqual(extrema("I;16"), (0, 255))
def test_true_16(self):
im = Image.open("Tests/images/16_bit_noise.tif")
self.assertEqual(im.mode, "I;16")
extrema = im.getextrema()
with Image.open("Tests/images/16_bit_noise.tif") as im:
self.assertEqual(im.mode, "I;16")
extrema = im.getextrema()
self.assertEqual(extrema, (106, 285))

View File

@ -1,5 +1,3 @@
from PIL._util import py3
from .helper import PillowTestCase, hopper
@ -8,7 +6,5 @@ class TestImageGetIm(PillowTestCase):
im = hopper()
type_repr = repr(type(im.getim()))
if py3:
self.assertIn("PyCapsule", type_repr)
self.assertIn("PyCapsule", type_repr)
self.assertIsInstance(im.im.id, int)

View File

@ -42,21 +42,24 @@ class TestImageQuantize(PillowTestCase):
self.assertEqual(image.quantize().convert().mode, "RGBA")
def test_quantize(self):
image = Image.open("Tests/images/caption_6_33_22.png").convert("RGB")
with Image.open("Tests/images/caption_6_33_22.png") as image:
image = image.convert("RGB")
converted = image.quantize()
self.assert_image(converted, "P", converted.size)
self.assert_image_similar(converted.convert("RGB"), image, 1)
def test_quantize_no_dither(self):
image = hopper()
palette = Image.open("Tests/images/caption_6_33_22.png").convert("P")
with Image.open("Tests/images/caption_6_33_22.png") as palette:
palette = palette.convert("P")
converted = image.quantize(dither=0, palette=palette)
self.assert_image(converted, "P", converted.size)
def test_quantize_dither_diff(self):
image = hopper()
palette = Image.open("Tests/images/caption_6_33_22.png").convert("P")
with Image.open("Tests/images/caption_6_33_22.png") as palette:
palette = palette.convert("P")
dither = image.quantize(dither=1, palette=palette)
nodither = image.quantize(dither=0, palette=palette)

View File

@ -1,10 +1,9 @@
from __future__ import division, print_function
import unittest
from contextlib import contextmanager
from PIL import Image, ImageDraw
from .helper import PillowTestCase, hopper, unittest
from .helper import PillowTestCase, hopper
class TestImagingResampleVulnerability(PillowTestCase):
@ -451,25 +450,25 @@ class CoreResampleBoxTest(PillowTestCase):
return tiled
def test_tiles(self):
im = Image.open("Tests/images/flower.jpg")
self.assertEqual(im.size, (480, 360))
dst_size = (251, 188)
reference = im.resize(dst_size, Image.BICUBIC)
with Image.open("Tests/images/flower.jpg") as im:
self.assertEqual(im.size, (480, 360))
dst_size = (251, 188)
reference = im.resize(dst_size, Image.BICUBIC)
for tiles in [(1, 1), (3, 3), (9, 7), (100, 100)]:
tiled = self.resize_tiled(im, dst_size, *tiles)
self.assert_image_similar(reference, tiled, 0.01)
for tiles in [(1, 1), (3, 3), (9, 7), (100, 100)]:
tiled = self.resize_tiled(im, dst_size, *tiles)
self.assert_image_similar(reference, tiled, 0.01)
def test_subsample(self):
# This test shows advantages of the subpixel resizing
# after supersampling (e.g. during JPEG decoding).
im = Image.open("Tests/images/flower.jpg")
self.assertEqual(im.size, (480, 360))
dst_size = (48, 36)
# Reference is cropped image resized to destination
reference = im.crop((0, 0, 473, 353)).resize(dst_size, Image.BICUBIC)
# Image.BOX emulates supersampling (480 / 8 = 60, 360 / 8 = 45)
supersampled = im.resize((60, 45), Image.BOX)
with Image.open("Tests/images/flower.jpg") as im:
self.assertEqual(im.size, (480, 360))
dst_size = (48, 36)
# Reference is cropped image resized to destination
reference = im.crop((0, 0, 473, 353)).resize(dst_size, Image.BICUBIC)
# Image.BOX emulates supersampling (480 / 8 = 60, 360 / 8 = 45)
supersampled = im.resize((60, 45), Image.BOX)
with_box = supersampled.resize(dst_size, Image.BICUBIC, (0, 0, 59.125, 44.125))
without_box = supersampled.resize(dst_size, Image.BICUBIC)

View File

@ -24,8 +24,8 @@ class TestImageRotate(PillowTestCase):
def test_angle(self):
for angle in (0, 90, 180, 270):
im = Image.open("Tests/images/test-card.png")
self.rotate(im, im.mode, angle)
with Image.open("Tests/images/test-card.png") as im:
self.rotate(im, im.mode, angle)
def test_zero(self):
for angle in (0, 45, 90, 180, 270):
@ -38,43 +38,43 @@ class TestImageRotate(PillowTestCase):
# >>> im = im.rotate(45, resample=Image.BICUBIC, expand=True)
# >>> im.save('Tests/images/hopper_45.png')
target = Image.open("Tests/images/hopper_45.png")
for (resample, epsilon) in (
(Image.NEAREST, 10),
(Image.BILINEAR, 5),
(Image.BICUBIC, 0),
):
im = hopper()
im = im.rotate(45, resample=resample, expand=True)
self.assert_image_similar(im, target, epsilon)
with Image.open("Tests/images/hopper_45.png") as target:
for (resample, epsilon) in (
(Image.NEAREST, 10),
(Image.BILINEAR, 5),
(Image.BICUBIC, 0),
):
im = hopper()
im = im.rotate(45, resample=resample, expand=True)
self.assert_image_similar(im, target, epsilon)
def test_center_0(self):
im = hopper()
target = Image.open("Tests/images/hopper_45.png")
target_origin = target.size[1] / 2
target = target.crop((0, target_origin, 128, target_origin + 128))
im = im.rotate(45, center=(0, 0), resample=Image.BICUBIC)
with Image.open("Tests/images/hopper_45.png") as target:
target_origin = target.size[1] / 2
target = target.crop((0, target_origin, 128, target_origin + 128))
self.assert_image_similar(im, target, 15)
def test_center_14(self):
im = hopper()
target = Image.open("Tests/images/hopper_45.png")
target_origin = target.size[1] / 2 - 14
target = target.crop((6, target_origin, 128 + 6, target_origin + 128))
im = im.rotate(45, center=(14, 14), resample=Image.BICUBIC)
self.assert_image_similar(im, target, 10)
with Image.open("Tests/images/hopper_45.png") as target:
target_origin = target.size[1] / 2 - 14
target = target.crop((6, target_origin, 128 + 6, target_origin + 128))
self.assert_image_similar(im, target, 10)
def test_translate(self):
im = hopper()
target = Image.open("Tests/images/hopper_45.png")
target_origin = (target.size[1] / 2 - 64) - 5
target = target.crop(
(target_origin, target_origin, target_origin + 128, target_origin + 128)
)
with Image.open("Tests/images/hopper_45.png") as target:
target_origin = (target.size[1] / 2 - 64) - 5
target = target.crop(
(target_origin, target_origin, target_origin + 128, target_origin + 128)
)
im = im.rotate(45, translate=(5, 5), resample=Image.BICUBIC)
@ -102,15 +102,15 @@ class TestImageRotate(PillowTestCase):
def test_rotate_no_fill(self):
im = Image.new("RGB", (100, 100), "green")
target = Image.open("Tests/images/rotate_45_no_fill.png")
im = im.rotate(45)
self.assert_image_equal(im, target)
with Image.open("Tests/images/rotate_45_no_fill.png") as target:
self.assert_image_equal(im, target)
def test_rotate_with_fill(self):
im = Image.new("RGB", (100, 100), "green")
target = Image.open("Tests/images/rotate_45_with_fill.png")
im = im.rotate(45, fillcolor="white")
self.assert_image_equal(im, target)
with Image.open("Tests/images/rotate_45_with_fill.png") as target:
self.assert_image_equal(im, target)
def test_alpha_rotate_no_fill(self):
# Alpha images are handled differently internally

View File

@ -53,8 +53,8 @@ class TestImageSplit(PillowTestCase):
def split_open(mode):
hopper(mode).save(test_file)
im = Image.open(test_file)
return len(im.split())
with Image.open(test_file) as im:
return len(im.split())
self.assertEqual(split_open("1"), 1)
self.assertEqual(split_open("L"), 1)

View File

@ -23,11 +23,11 @@ class TestImageTransform(PillowTestCase):
def test_info(self):
comment = b"File written by Adobe Photoshop\xa8 4.0"
im = Image.open("Tests/images/hopper.gif")
self.assertEqual(im.info["comment"], comment)
with Image.open("Tests/images/hopper.gif") as im:
self.assertEqual(im.info["comment"], comment)
transform = ImageTransform.ExtentTransform((0, 0, 0, 0))
new_im = im.transform((100, 100), transform)
transform = ImageTransform.ExtentTransform((0, 0, 0, 0))
new_im = im.transform((100, 100), transform)
self.assertEqual(new_im.info["comment"], comment)
def test_extent(self):

View File

@ -45,11 +45,11 @@ class TestImageChops(PillowTestCase):
def test_add(self):
# Arrange
im1 = Image.open("Tests/images/imagedraw_ellipse_RGB.png")
im2 = Image.open("Tests/images/imagedraw_floodfill_RGB.png")
with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1:
with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2:
# Act
new = ImageChops.add(im1, im2)
# Act
new = ImageChops.add(im1, im2)
# Assert
self.assertEqual(new.getbbox(), (25, 25, 76, 76))
@ -57,11 +57,11 @@ class TestImageChops(PillowTestCase):
def test_add_scale_offset(self):
# Arrange
im1 = Image.open("Tests/images/imagedraw_ellipse_RGB.png")
im2 = Image.open("Tests/images/imagedraw_floodfill_RGB.png")
with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1:
with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2:
# Act
new = ImageChops.add(im1, im2, scale=2.5, offset=100)
# Act
new = ImageChops.add(im1, im2, scale=2.5, offset=100)
# Assert
self.assertEqual(new.getbbox(), (0, 0, 100, 100))
@ -79,11 +79,11 @@ class TestImageChops(PillowTestCase):
def test_add_modulo(self):
# Arrange
im1 = Image.open("Tests/images/imagedraw_ellipse_RGB.png")
im2 = Image.open("Tests/images/imagedraw_floodfill_RGB.png")
with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1:
with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2:
# Act
new = ImageChops.add_modulo(im1, im2)
# Act
new = ImageChops.add_modulo(im1, im2)
# Assert
self.assertEqual(new.getbbox(), (25, 25, 76, 76))
@ -101,11 +101,11 @@ class TestImageChops(PillowTestCase):
def test_blend(self):
# Arrange
im1 = Image.open("Tests/images/imagedraw_ellipse_RGB.png")
im2 = Image.open("Tests/images/imagedraw_floodfill_RGB.png")
with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1:
with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2:
# Act
new = ImageChops.blend(im1, im2, 0.5)
# Act
new = ImageChops.blend(im1, im2, 0.5)
# Assert
self.assertEqual(new.getbbox(), (25, 25, 76, 76))
@ -125,33 +125,33 @@ class TestImageChops(PillowTestCase):
def test_darker_image(self):
# Arrange
im1 = Image.open("Tests/images/imagedraw_chord_RGB.png")
im2 = Image.open("Tests/images/imagedraw_outline_chord_RGB.png")
with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1:
with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2:
# Act
new = ImageChops.darker(im1, im2)
# Act
new = ImageChops.darker(im1, im2)
# Assert
self.assert_image_equal(new, im2)
# Assert
self.assert_image_equal(new, im2)
def test_darker_pixel(self):
# Arrange
im1 = hopper()
im2 = Image.open("Tests/images/imagedraw_chord_RGB.png")
with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2:
# Act
new = ImageChops.darker(im1, im2)
# Act
new = ImageChops.darker(im1, im2)
# Assert
self.assertEqual(new.getpixel((50, 50)), (240, 166, 0))
def test_difference(self):
# Arrange
im1 = Image.open("Tests/images/imagedraw_arc_end_le_start.png")
im2 = Image.open("Tests/images/imagedraw_arc_no_loops.png")
with Image.open("Tests/images/imagedraw_arc_end_le_start.png") as im1:
with Image.open("Tests/images/imagedraw_arc_no_loops.png") as im2:
# Act
new = ImageChops.difference(im1, im2)
# Act
new = ImageChops.difference(im1, im2)
# Assert
self.assertEqual(new.getbbox(), (25, 25, 76, 76))
@ -159,10 +159,10 @@ class TestImageChops(PillowTestCase):
def test_difference_pixel(self):
# Arrange
im1 = hopper()
im2 = Image.open("Tests/images/imagedraw_polygon_kite_RGB.png")
with Image.open("Tests/images/imagedraw_polygon_kite_RGB.png") as im2:
# Act
new = ImageChops.difference(im1, im2)
# Act
new = ImageChops.difference(im1, im2)
# Assert
self.assertEqual(new.getpixel((50, 50)), (240, 166, 128))
@ -179,10 +179,10 @@ class TestImageChops(PillowTestCase):
def test_invert(self):
# Arrange
im = Image.open("Tests/images/imagedraw_floodfill_RGB.png")
with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im:
# Act
new = ImageChops.invert(im)
# Act
new = ImageChops.invert(im)
# Assert
self.assertEqual(new.getbbox(), (0, 0, 100, 100))
@ -191,11 +191,11 @@ class TestImageChops(PillowTestCase):
def test_lighter_image(self):
# Arrange
im1 = Image.open("Tests/images/imagedraw_chord_RGB.png")
im2 = Image.open("Tests/images/imagedraw_outline_chord_RGB.png")
with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1:
with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2:
# Act
new = ImageChops.lighter(im1, im2)
# Act
new = ImageChops.lighter(im1, im2)
# Assert
self.assert_image_equal(new, im1)
@ -203,10 +203,10 @@ class TestImageChops(PillowTestCase):
def test_lighter_pixel(self):
# Arrange
im1 = hopper()
im2 = Image.open("Tests/images/imagedraw_chord_RGB.png")
with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2:
# Act
new = ImageChops.lighter(im1, im2)
# Act
new = ImageChops.lighter(im1, im2)
# Assert
self.assertEqual(new.getpixel((50, 50)), (255, 255, 127))
@ -226,11 +226,11 @@ class TestImageChops(PillowTestCase):
def test_multiply_green(self):
# Arrange
im = Image.open("Tests/images/imagedraw_floodfill_RGB.png")
green = Image.new("RGB", im.size, "green")
with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im:
green = Image.new("RGB", im.size, "green")
# Act
new = ImageChops.multiply(im, green)
# Act
new = ImageChops.multiply(im, green)
# Assert
self.assertEqual(new.getbbox(), (25, 25, 76, 76))
@ -252,12 +252,12 @@ class TestImageChops(PillowTestCase):
def test_offset(self):
# Arrange
im = Image.open("Tests/images/imagedraw_ellipse_RGB.png")
xoffset = 45
yoffset = 20
with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im:
# Act
new = ImageChops.offset(im, xoffset, yoffset)
# Act
new = ImageChops.offset(im, xoffset, yoffset)
# Assert
self.assertEqual(new.getbbox(), (0, 45, 100, 96))
@ -271,11 +271,11 @@ class TestImageChops(PillowTestCase):
def test_screen(self):
# Arrange
im1 = Image.open("Tests/images/imagedraw_ellipse_RGB.png")
im2 = Image.open("Tests/images/imagedraw_floodfill_RGB.png")
with Image.open("Tests/images/imagedraw_ellipse_RGB.png") as im1:
with Image.open("Tests/images/imagedraw_floodfill_RGB.png") as im2:
# Act
new = ImageChops.screen(im1, im2)
# Act
new = ImageChops.screen(im1, im2)
# Assert
self.assertEqual(new.getbbox(), (25, 25, 76, 76))
@ -283,11 +283,11 @@ class TestImageChops(PillowTestCase):
def test_subtract(self):
# Arrange
im1 = Image.open("Tests/images/imagedraw_chord_RGB.png")
im2 = Image.open("Tests/images/imagedraw_outline_chord_RGB.png")
with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1:
with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2:
# Act
new = ImageChops.subtract(im1, im2)
# Act
new = ImageChops.subtract(im1, im2)
# Assert
self.assertEqual(new.getbbox(), (25, 50, 76, 76))
@ -296,11 +296,11 @@ class TestImageChops(PillowTestCase):
def test_subtract_scale_offset(self):
# Arrange
im1 = Image.open("Tests/images/imagedraw_chord_RGB.png")
im2 = Image.open("Tests/images/imagedraw_outline_chord_RGB.png")
with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1:
with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2:
# Act
new = ImageChops.subtract(im1, im2, scale=2.5, offset=100)
# Act
new = ImageChops.subtract(im1, im2, scale=2.5, offset=100)
# Assert
self.assertEqual(new.getbbox(), (0, 0, 100, 100))
@ -309,21 +309,21 @@ class TestImageChops(PillowTestCase):
def test_subtract_clip(self):
# Arrange
im1 = hopper()
im2 = Image.open("Tests/images/imagedraw_chord_RGB.png")
with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2:
# Act
new = ImageChops.subtract(im1, im2)
# Act
new = ImageChops.subtract(im1, im2)
# Assert
self.assertEqual(new.getpixel((50, 50)), (0, 0, 127))
def test_subtract_modulo(self):
# Arrange
im1 = Image.open("Tests/images/imagedraw_chord_RGB.png")
im2 = Image.open("Tests/images/imagedraw_outline_chord_RGB.png")
with Image.open("Tests/images/imagedraw_chord_RGB.png") as im1:
with Image.open("Tests/images/imagedraw_outline_chord_RGB.png") as im2:
# Act
new = ImageChops.subtract_modulo(im1, im2)
# Act
new = ImageChops.subtract_modulo(im1, im2)
# Assert
self.assertEqual(new.getbbox(), (25, 50, 76, 76))
@ -333,10 +333,10 @@ class TestImageChops(PillowTestCase):
def test_subtract_modulo_no_clip(self):
# Arrange
im1 = hopper()
im2 = Image.open("Tests/images/imagedraw_chord_RGB.png")
with Image.open("Tests/images/imagedraw_chord_RGB.png") as im2:
# Act
new = ImageChops.subtract_modulo(im1, im2)
# Act
new = ImageChops.subtract_modulo(im1, im2)
# Assert
self.assertEqual(new.getpixel((50, 50)), (241, 167, 127))

View File

@ -229,18 +229,16 @@ class TestImageCms(PillowTestCase):
# i.save('temp.lab.tif') # visually verified vs PS.
target = Image.open("Tests/images/hopper.Lab.tif")
self.assert_image_similar(i, target, 3.5)
with Image.open("Tests/images/hopper.Lab.tif") as target:
self.assert_image_similar(i, target, 3.5)
def test_lab_srgb(self):
psRGB = ImageCms.createProfile("sRGB")
pLab = ImageCms.createProfile("LAB")
t = ImageCms.buildTransform(pLab, psRGB, "LAB", "RGB")
img = Image.open("Tests/images/hopper.Lab.tif")
img_srgb = ImageCms.applyTransform(img, t)
with Image.open("Tests/images/hopper.Lab.tif") as img:
img_srgb = ImageCms.applyTransform(img, t)
# img_srgb.save('temp.srgb.tif') # visually verified vs ps.

View File

@ -1,8 +1,9 @@
import os.path
import unittest
from PIL import Image, ImageColor, ImageDraw, ImageFont, features
from .helper import PillowTestCase, hopper, unittest
from .helper import PillowTestCase, hopper
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
@ -156,12 +157,12 @@ class TestImageDraw(PillowTestCase):
def test_bitmap(self):
# Arrange
small = Image.open("Tests/images/pil123rgba.png").resize((50, 50))
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
with Image.open("Tests/images/pil123rgba.png").resize((50, 50)) as small:
# Act
draw.bitmap((10, 10), small)
# Act
draw.bitmap((10, 10), small)
# Assert
self.assert_image_equal(im, Image.open("Tests/images/imagedraw_bitmap.png"))
@ -522,8 +523,8 @@ class TestImageDraw(PillowTestCase):
# Assert
expected = "Tests/images/imagedraw_floodfill_" + mode + ".png"
im_floodfill = Image.open(expected)
self.assert_image_equal(im, im_floodfill)
with Image.open(expected) as im_floodfill:
self.assert_image_equal(im, im_floodfill)
# Test that using the same colour does not change the image
ImageDraw.floodfill(im, centre_point, red)
@ -602,152 +603,166 @@ class TestImageDraw(PillowTestCase):
return img, ImageDraw.Draw(img)
def test_square(self):
expected = Image.open(os.path.join(IMAGES_PATH, "square.png"))
expected.load()
img, draw = self.create_base_image_draw((10, 10))
draw.polygon([(2, 2), (2, 7), (7, 7), (7, 2)], BLACK)
self.assert_image_equal(img, expected, "square as normal polygon failed")
img, draw = self.create_base_image_draw((10, 10))
draw.polygon([(7, 7), (7, 2), (2, 2), (2, 7)], BLACK)
self.assert_image_equal(img, expected, "square as inverted polygon failed")
img, draw = self.create_base_image_draw((10, 10))
draw.rectangle((2, 2, 7, 7), BLACK)
self.assert_image_equal(img, expected, "square as normal rectangle failed")
img, draw = self.create_base_image_draw((10, 10))
draw.rectangle((7, 7, 2, 2), BLACK)
self.assert_image_equal(img, expected, "square as inverted rectangle failed")
with Image.open(os.path.join(IMAGES_PATH, "square.png")) as expected:
expected.load()
img, draw = self.create_base_image_draw((10, 10))
draw.polygon([(2, 2), (2, 7), (7, 7), (7, 2)], BLACK)
self.assert_image_equal(img, expected, "square as normal polygon failed")
img, draw = self.create_base_image_draw((10, 10))
draw.polygon([(7, 7), (7, 2), (2, 2), (2, 7)], BLACK)
self.assert_image_equal(img, expected, "square as inverted polygon failed")
img, draw = self.create_base_image_draw((10, 10))
draw.rectangle((2, 2, 7, 7), BLACK)
self.assert_image_equal(img, expected, "square as normal rectangle failed")
img, draw = self.create_base_image_draw((10, 10))
draw.rectangle((7, 7, 2, 2), BLACK)
self.assert_image_equal(
img, expected, "square as inverted rectangle failed"
)
def test_triangle_right(self):
expected = Image.open(os.path.join(IMAGES_PATH, "triangle_right.png"))
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.polygon([(3, 5), (17, 5), (10, 12)], BLACK)
self.assert_image_equal(img, expected, "triangle right failed")
with Image.open(os.path.join(IMAGES_PATH, "triangle_right.png")) as expected:
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.polygon([(3, 5), (17, 5), (10, 12)], BLACK)
self.assert_image_equal(img, expected, "triangle right failed")
def test_line_horizontal(self):
expected = Image.open(
with Image.open(
os.path.join(IMAGES_PATH, "line_horizontal_w2px_normal.png")
)
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 5), BLACK, 2)
self.assert_image_equal(
img, expected, "line straight horizontal normal 2px wide failed"
)
expected = Image.open(
) as expected:
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 5), BLACK, 2)
self.assert_image_equal(
img, expected, "line straight horizontal normal 2px wide failed"
)
with Image.open(
os.path.join(IMAGES_PATH, "line_horizontal_w2px_inverted.png")
)
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 5, 5, 5), BLACK, 2)
self.assert_image_equal(
img, expected, "line straight horizontal inverted 2px wide failed"
)
expected = Image.open(os.path.join(IMAGES_PATH, "line_horizontal_w3px.png"))
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 5), BLACK, 3)
self.assert_image_equal(
img, expected, "line straight horizontal normal 3px wide failed"
)
img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 5, 5, 5), BLACK, 3)
self.assert_image_equal(
img, expected, "line straight horizontal inverted 3px wide failed"
)
expected = Image.open(os.path.join(IMAGES_PATH, "line_horizontal_w101px.png"))
expected.load()
img, draw = self.create_base_image_draw((200, 110))
draw.line((5, 55, 195, 55), BLACK, 101)
self.assert_image_equal(
img, expected, "line straight horizontal 101px wide failed"
)
) as expected:
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 5, 5, 5), BLACK, 2)
self.assert_image_equal(
img, expected, "line straight horizontal inverted 2px wide failed"
)
with Image.open(
os.path.join(IMAGES_PATH, "line_horizontal_w3px.png")
) as expected:
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 5), BLACK, 3)
self.assert_image_equal(
img, expected, "line straight horizontal normal 3px wide failed"
)
img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 5, 5, 5), BLACK, 3)
self.assert_image_equal(
img, expected, "line straight horizontal inverted 3px wide failed"
)
with Image.open(
os.path.join(IMAGES_PATH, "line_horizontal_w101px.png")
) as expected:
expected.load()
img, draw = self.create_base_image_draw((200, 110))
draw.line((5, 55, 195, 55), BLACK, 101)
self.assert_image_equal(
img, expected, "line straight horizontal 101px wide failed"
)
def test_line_h_s1_w2(self):
self.skipTest("failing")
expected = Image.open(
with Image.open(
os.path.join(IMAGES_PATH, "line_horizontal_slope1px_w2px.png")
)
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 6), BLACK, 2)
self.assert_image_equal(
img, expected, "line horizontal 1px slope 2px wide failed"
)
) as expected:
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 6), BLACK, 2)
self.assert_image_equal(
img, expected, "line horizontal 1px slope 2px wide failed"
)
def test_line_vertical(self):
expected = Image.open(
with Image.open(
os.path.join(IMAGES_PATH, "line_vertical_w2px_normal.png")
)
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 5, 14), BLACK, 2)
self.assert_image_equal(
img, expected, "line straight vertical normal 2px wide failed"
)
expected = Image.open(
) as expected:
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 5, 14), BLACK, 2)
self.assert_image_equal(
img, expected, "line straight vertical normal 2px wide failed"
)
with Image.open(
os.path.join(IMAGES_PATH, "line_vertical_w2px_inverted.png")
)
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 14, 5, 5), BLACK, 2)
self.assert_image_equal(
img, expected, "line straight vertical inverted 2px wide failed"
)
expected = Image.open(os.path.join(IMAGES_PATH, "line_vertical_w3px.png"))
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 5, 14), BLACK, 3)
self.assert_image_equal(
img, expected, "line straight vertical normal 3px wide failed"
)
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 14, 5, 5), BLACK, 3)
self.assert_image_equal(
img, expected, "line straight vertical inverted 3px wide failed"
)
expected = Image.open(os.path.join(IMAGES_PATH, "line_vertical_w101px.png"))
expected.load()
img, draw = self.create_base_image_draw((110, 200))
draw.line((55, 5, 55, 195), BLACK, 101)
self.assert_image_equal(
img, expected, "line straight vertical 101px wide failed"
)
expected = Image.open(
) as expected:
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 14, 5, 5), BLACK, 2)
self.assert_image_equal(
img, expected, "line straight vertical inverted 2px wide failed"
)
with Image.open(
os.path.join(IMAGES_PATH, "line_vertical_w3px.png")
) as expected:
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 5, 14), BLACK, 3)
self.assert_image_equal(
img, expected, "line straight vertical normal 3px wide failed"
)
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 14, 5, 5), BLACK, 3)
self.assert_image_equal(
img, expected, "line straight vertical inverted 3px wide failed"
)
with Image.open(
os.path.join(IMAGES_PATH, "line_vertical_w101px.png")
) as expected:
expected.load()
img, draw = self.create_base_image_draw((110, 200))
draw.line((55, 5, 55, 195), BLACK, 101)
self.assert_image_equal(
img, expected, "line straight vertical 101px wide failed"
)
with Image.open(
os.path.join(IMAGES_PATH, "line_vertical_slope1px_w2px.png")
)
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 6, 14), BLACK, 2)
self.assert_image_equal(
img, expected, "line vertical 1px slope 2px wide failed"
)
) as expected:
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 6, 14), BLACK, 2)
self.assert_image_equal(
img, expected, "line vertical 1px slope 2px wide failed"
)
def test_line_oblique_45(self):
expected = Image.open(os.path.join(IMAGES_PATH, "line_oblique_45_w3px_a.png"))
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 14), BLACK, 3)
self.assert_image_equal(
img, expected, "line oblique 45 normal 3px wide A failed"
)
img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 14, 5, 5), BLACK, 3)
self.assert_image_equal(
img, expected, "line oblique 45 inverted 3px wide A failed"
)
expected = Image.open(os.path.join(IMAGES_PATH, "line_oblique_45_w3px_b.png"))
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 5, 5, 14), BLACK, 3)
self.assert_image_equal(
img, expected, "line oblique 45 normal 3px wide B failed"
)
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 14, 14, 5), BLACK, 3)
self.assert_image_equal(
img, expected, "line oblique 45 inverted 3px wide B failed"
)
with Image.open(
os.path.join(IMAGES_PATH, "line_oblique_45_w3px_a.png")
) as expected:
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 5, 14, 14), BLACK, 3)
self.assert_image_equal(
img, expected, "line oblique 45 normal 3px wide A failed"
)
img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 14, 5, 5), BLACK, 3)
self.assert_image_equal(
img, expected, "line oblique 45 inverted 3px wide A failed"
)
with Image.open(
os.path.join(IMAGES_PATH, "line_oblique_45_w3px_b.png")
) as expected:
expected.load()
img, draw = self.create_base_image_draw((20, 20))
draw.line((14, 5, 5, 14), BLACK, 3)
self.assert_image_equal(
img, expected, "line oblique 45 normal 3px wide B failed"
)
img, draw = self.create_base_image_draw((20, 20))
draw.line((5, 14, 14, 5), BLACK, 3)
self.assert_image_equal(
img, expected, "line oblique 45 inverted 3px wide B failed"
)
def test_wide_line_dot(self):
# Test drawing a wide "line" from one point to another just draws

View File

@ -1,8 +1,9 @@
import os.path
import unittest
from PIL import Image, ImageDraw2, features
from .helper import PillowTestCase, hopper, unittest
from .helper import PillowTestCase, hopper
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

View File

@ -35,7 +35,7 @@ class TestImageEnhance(PillowTestCase):
self.assert_image_equal(
im.getchannel("A"),
original.getchannel("A"),
"Diff on %s: %s" % (op, amount),
"Diff on {}: {}".format(op, amount),
)
def test_alpha(self):

View File

@ -1,8 +1,9 @@
import unittest
from io import BytesIO
from PIL import EpsImagePlugin, Image, ImageFile
from .helper import PillowTestCase, fromstring, hopper, tostring, unittest
from .helper import PillowTestCase, fromstring, hopper, tostring
try:
from PIL import _webp
@ -127,33 +128,31 @@ class TestImageFile(PillowTestCase):
if "zip_encoder" not in codecs:
self.skipTest("PNG (zlib) encoder not available")
im = Image.open("Tests/images/truncated_image.png")
ImageFile.LOAD_TRUNCATED_IMAGES = True
try:
im.load()
finally:
ImageFile.LOAD_TRUNCATED_IMAGES = False
with Image.open("Tests/images/truncated_image.png") as im:
ImageFile.LOAD_TRUNCATED_IMAGES = True
try:
im.load()
finally:
ImageFile.LOAD_TRUNCATED_IMAGES = False
def test_broken_datastream_with_errors(self):
if "zip_encoder" not in codecs:
self.skipTest("PNG (zlib) encoder not available")
im = Image.open("Tests/images/broken_data_stream.png")
with self.assertRaises(IOError):
im.load()
with Image.open("Tests/images/broken_data_stream.png") as im:
with self.assertRaises(IOError):
im.load()
def test_broken_datastream_without_errors(self):
if "zip_encoder" not in codecs:
self.skipTest("PNG (zlib) encoder not available")
im = Image.open("Tests/images/broken_data_stream.png")
ImageFile.LOAD_TRUNCATED_IMAGES = True
try:
im.load()
finally:
ImageFile.LOAD_TRUNCATED_IMAGES = False
with Image.open("Tests/images/broken_data_stream.png") as im:
ImageFile.LOAD_TRUNCATED_IMAGES = True
try:
im.load()
finally:
ImageFile.LOAD_TRUNCATED_IMAGES = False
class MockPyDecoder(ImageFile.PyDecoder):
@ -245,19 +244,19 @@ class TestPyDecoder(PillowTestCase):
self.assertIsNone(im.get_format_mimetype())
def test_exif_jpeg(self):
im = Image.open("Tests/images/exif-72dpi-int.jpg") # Little endian
exif = im.getexif()
self.assertNotIn(258, exif)
self.assertIn(40960, exif)
self.assertEqual(exif[40963], 450)
self.assertEqual(exif[11], "gThumb 3.0.1")
with Image.open("Tests/images/exif-72dpi-int.jpg") as im: # Little endian
exif = im.getexif()
self.assertNotIn(258, exif)
self.assertIn(40960, exif)
self.assertEqual(exif[40963], 450)
self.assertEqual(exif[11], "gThumb 3.0.1")
out = self.tempfile("temp.jpg")
exif[258] = 8
del exif[40960]
exif[40963] = 455
exif[11] = "Pillow test"
im.save(out, exif=exif)
out = self.tempfile("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()
self.assertEqual(reloaded_exif[258], 8)
@ -265,19 +264,19 @@ class TestPyDecoder(PillowTestCase):
self.assertEqual(reloaded_exif[40963], 455)
self.assertEqual(exif[11], "Pillow test")
im = Image.open("Tests/images/no-dpi-in-exif.jpg") # Big endian
exif = im.getexif()
self.assertNotIn(258, exif)
self.assertIn(40962, exif)
self.assertEqual(exif[40963], 200)
self.assertEqual(exif[305], "Adobe Photoshop CC 2017 (Macintosh)")
with Image.open("Tests/images/no-dpi-in-exif.jpg") as im: # Big endian
exif = im.getexif()
self.assertNotIn(258, exif)
self.assertIn(40962, exif)
self.assertEqual(exif[40963], 200)
self.assertEqual(exif[305], "Adobe Photoshop CC 2017 (Macintosh)")
out = self.tempfile("temp.jpg")
exif[258] = 8
del exif[34665]
exif[40963] = 455
exif[305] = "Pillow test"
im.save(out, exif=exif)
out = self.tempfile("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()
self.assertEqual(reloaded_exif[258], 8)
@ -290,38 +289,38 @@ class TestPyDecoder(PillowTestCase):
"WebP support not installed with animation",
)
def test_exif_webp(self):
im = Image.open("Tests/images/hopper.webp")
exif = im.getexif()
self.assertEqual(exif, {})
with Image.open("Tests/images/hopper.webp") as im:
exif = im.getexif()
self.assertEqual(exif, {})
out = self.tempfile("temp.webp")
exif[258] = 8
exif[40963] = 455
exif[305] = "Pillow test"
out = self.tempfile("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()
self.assertEqual(reloaded_exif[258], 8)
self.assertEqual(reloaded_exif[40963], 455)
self.assertEqual(exif[305], "Pillow test")
def check_exif():
with Image.open(out) as reloaded:
reloaded_exif = reloaded.getexif()
self.assertEqual(reloaded_exif[258], 8)
self.assertEqual(reloaded_exif[40963], 455)
self.assertEqual(exif[305], "Pillow test")
im.save(out, exif=exif)
check_exif()
im.save(out, exif=exif, save_all=True)
check_exif()
im.save(out, exif=exif)
check_exif()
im.save(out, exif=exif, save_all=True)
check_exif()
def test_exif_png(self):
im = Image.open("Tests/images/exif.png")
exif = im.getexif()
self.assertEqual(exif, {274: 1})
with Image.open("Tests/images/exif.png") as im:
exif = im.getexif()
self.assertEqual(exif, {274: 1})
out = self.tempfile("temp.png")
exif[258] = 8
del exif[274]
exif[40963] = 455
exif[305] = "Pillow test"
im.save(out, exif=exif)
out = self.tempfile("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()

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