Merge branch 'master' into bomb
Conflicts: PIL/Image.py
11
.coveragerc
Normal file
|
@ -0,0 +1,11 @@
|
|||
# .coveragerc to control coverage.py
|
||||
|
||||
[report]
|
||||
# Regexes for lines to exclude from consideration
|
||||
exclude_lines =
|
||||
# Have to re-enable the standard pragma:
|
||||
pragma: no cover
|
||||
|
||||
# Don't complain if non-runnable code isn't run:
|
||||
if 0:
|
||||
if __name__ == .__main__.:
|
25
.travis.yml
|
@ -14,7 +14,8 @@ python:
|
|||
install:
|
||||
- "sudo apt-get -qq install libfreetype6-dev liblcms2-dev python-qt4 ghostscript libffi-dev cmake"
|
||||
- "pip install cffi"
|
||||
- "pip install coveralls"
|
||||
- "pip install coveralls nose"
|
||||
- if [ "$TRAVIS_PYTHON_VERSION" == "2.6" ]; then pip install unittest2; fi
|
||||
|
||||
# webp
|
||||
- pushd depends && ./install_webp.sh && popd
|
||||
|
@ -26,18 +27,20 @@ script:
|
|||
- coverage erase
|
||||
- python setup.py clean
|
||||
- python setup.py build_ext --inplace
|
||||
- coverage run --append --include=PIL/* selftest.py
|
||||
- python Tests/run.py --coverage
|
||||
|
||||
# Don't cover PyPy: it fails intermittently and is x5.8 slower (#640)
|
||||
- if [ "$TRAVIS_PYTHON_VERSION" == "pypy" ]; then time python selftest.py; fi
|
||||
- if [ "$TRAVIS_PYTHON_VERSION" == "pypy" ]; then time nosetests Tests/test_*.py; fi
|
||||
|
||||
# Cover the others
|
||||
- if [ "$TRAVIS_PYTHON_VERSION" != "pypy" ]; then time coverage run --append --include=PIL/* selftest.py; fi
|
||||
- if [ "$TRAVIS_PYTHON_VERSION" != "pypy" ]; then time coverage run --append --include=PIL/* -m nose Tests/test_*.py; fi
|
||||
|
||||
after_success:
|
||||
- coverage report
|
||||
- coveralls
|
||||
- pip install pep8 pyflakes
|
||||
- pep8 PIL/*.py
|
||||
- pyflakes PIL/*.py
|
||||
- pep8 Tests/*.py
|
||||
- pyflakes Tests/*.py
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- python: "pypy"
|
||||
- pep8 --statistics --count PIL/*.py
|
||||
- pep8 --statistics --count Tests/*.py
|
||||
- pyflakes PIL/*.py | tee >(wc -l)
|
||||
- pyflakes Tests/*.py | tee >(wc -l)
|
||||
|
|
47
CHANGES.rst
|
@ -4,6 +4,51 @@ Changelog (Pillow)
|
|||
2.5.0 (unreleased)
|
||||
------------------
|
||||
|
||||
- Support OpenJpeg 2.1
|
||||
[wiredfool]
|
||||
|
||||
- Remove unistd.h #include for all platforms
|
||||
[wiredfool]
|
||||
|
||||
- Use unittest for tests
|
||||
[hugovk]
|
||||
|
||||
- ImageCms fixes
|
||||
[hugovk]
|
||||
|
||||
- Added more ImageDraw tests
|
||||
[hugovk]
|
||||
|
||||
- Added tests for Spider files
|
||||
[hugovk]
|
||||
|
||||
- Use libtiff to write any compressed tiff files
|
||||
[wiredfool]
|
||||
|
||||
- Support for pickling Image objects
|
||||
[hugovk]
|
||||
|
||||
- Fixed resolution handling for EPS thumbnails
|
||||
[eliempje]
|
||||
|
||||
- Fixed rendering of some binary EPS files (Issue #302)
|
||||
[eliempje]
|
||||
|
||||
- Rename variables not to use built-in function names
|
||||
[hugovk]
|
||||
|
||||
- Ignore junk JPEG markers
|
||||
[hugovk]
|
||||
|
||||
- Change default interpolation for Image.thumbnail to Image.ANTIALIAS
|
||||
[hugovk]
|
||||
|
||||
- Add tests and fixes for saving PDFs
|
||||
[hugovk]
|
||||
|
||||
- Remove transparency resource after P->RGBA conversion
|
||||
[hugovk]
|
||||
|
||||
- Clean up preprocessor cruft for Windows
|
||||
[CounterPillow]
|
||||
|
||||
|
@ -405,7 +450,7 @@ Changelog (Pillow)
|
|||
- Add Python 3 support. (Pillow >= 2.0.0 supports Python 2.6, 2.7, 3.2, 3.3. Pillow < 2.0.0 supports Python 2.4, 2.5, 2.6, 2.7.)
|
||||
[fluggo]
|
||||
|
||||
- Add PyPy support (experimental, please see: https://github.com/python-imaging/Pillow/issues/67)
|
||||
- Add PyPy support (experimental, please see: https://github.com/python-pillow/Pillow/issues/67)
|
||||
|
||||
- Add WebP support.
|
||||
[lqs]
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
# 1996-08-23 fl Handle files from Macintosh (0.3)
|
||||
# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4)
|
||||
# 2003-09-07 fl Check gs.close status (from Federico Di Gregorio) (0.5)
|
||||
# 2014-05-07 e Handling of EPS with binary preview and fixed resolution resizing
|
||||
#
|
||||
# Copyright (c) 1997-2003 by Secret Labs AB.
|
||||
# Copyright (c) 1995-2003 by Fredrik Lundh
|
||||
|
@ -77,8 +78,9 @@ def Ghostscript(tile, size, fp, scale=1):
|
|||
orig_size = size
|
||||
orig_bbox = bbox
|
||||
size = (size[0] * scale, size[1] * scale)
|
||||
bbox = [bbox[0], bbox[1], bbox[2] * scale, bbox[3] * scale]
|
||||
#print("Ghostscript", scale, size, orig_size, bbox, orig_bbox)
|
||||
# resolution is dependend on bbox and size
|
||||
res = ( float((72.0 * size[0]) / (bbox[2]-bbox[0])), float((72.0 * size[1]) / (bbox[3]-bbox[1])) )
|
||||
#print("Ghostscript", scale, size, orig_size, bbox, orig_bbox, res)
|
||||
|
||||
import tempfile, os, subprocess
|
||||
|
||||
|
@ -87,20 +89,29 @@ def Ghostscript(tile, size, fp, scale=1):
|
|||
in_fd, infile = tempfile.mkstemp()
|
||||
os.close(in_fd)
|
||||
|
||||
# ignore length and offset!
|
||||
# ghostscript can read it
|
||||
# copy whole file to read in ghostscript
|
||||
with open(infile, 'wb') as f:
|
||||
fp.seek(offset)
|
||||
while length >0:
|
||||
s = fp.read(100*1024)
|
||||
# fetch length of fp
|
||||
fp.seek(0, 2)
|
||||
fsize = fp.tell()
|
||||
# ensure start position
|
||||
# go back
|
||||
fp.seek(0)
|
||||
lengthfile = fsize
|
||||
while lengthfile > 0:
|
||||
s = fp.read(min(lengthfile, 100*1024))
|
||||
if not s:
|
||||
break
|
||||
length = length - len(s)
|
||||
lengthfile = lengthfile - len(s)
|
||||
f.write(s)
|
||||
|
||||
# Build ghostscript command
|
||||
command = ["gs",
|
||||
"-q", # quiet mode
|
||||
"-g%dx%d" % size, # set output geometry (pixels)
|
||||
"-r%d" % (72*scale), # set input DPI (dots per inch)
|
||||
"-r%fx%f" % res, # set input DPI (dots per inch)
|
||||
"-dNOPAUSE -dSAFER", # don't pause between pages, safe mode
|
||||
"-sDEVICE=ppmraw", # ppm driver
|
||||
"-sOutputFile=%s" % outfile, # output file
|
||||
|
@ -145,6 +156,8 @@ class PSFile:
|
|||
self.fp.seek(offset, whence)
|
||||
def read(self, count):
|
||||
return self.fp.read(count).decode('latin-1')
|
||||
def readbinary(self, count):
|
||||
return self.fp.read(count)
|
||||
def tell(self):
|
||||
pos = self.fp.tell()
|
||||
if self.char:
|
||||
|
@ -182,24 +195,32 @@ class EpsImageFile(ImageFile.ImageFile):
|
|||
|
||||
def _open(self):
|
||||
|
||||
# FIXME: should check the first 512 bytes to see if this
|
||||
# really is necessary (platform-dependent, though...)
|
||||
|
||||
fp = PSFile(self.fp)
|
||||
|
||||
# HEAD
|
||||
s = fp.read(512)
|
||||
# FIX for: Some EPS file not handled correctly / issue #302
|
||||
# EPS can contain binary data
|
||||
# or start directly with latin coding
|
||||
# read header in both ways to handle both
|
||||
# file types
|
||||
# more info see http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf
|
||||
|
||||
# for HEAD without binary preview
|
||||
s = fp.read(4)
|
||||
# for HEAD with binary preview
|
||||
fp.seek(0)
|
||||
sb = fp.readbinary(160)
|
||||
|
||||
if s[:4] == "%!PS":
|
||||
offset = 0
|
||||
fp.seek(0, 2)
|
||||
length = fp.tell()
|
||||
elif i32(s) == 0xC6D3D0C5:
|
||||
offset = i32(s[4:])
|
||||
length = i32(s[8:])
|
||||
fp.seek(offset)
|
||||
offset = 0
|
||||
elif i32(sb[0:4]) == 0xC6D3D0C5:
|
||||
offset = i32(sb[4:8])
|
||||
length = i32(sb[8:12])
|
||||
else:
|
||||
raise SyntaxError("not an EPS file")
|
||||
|
||||
# go to offset - start of "%!PS"
|
||||
fp.seek(offset)
|
||||
|
||||
box = None
|
||||
|
|
137
PIL/Image.py
|
@ -30,6 +30,7 @@ from PIL import VERSION, PILLOW_VERSION, _plugins
|
|||
|
||||
import warnings
|
||||
|
||||
|
||||
class _imaging_not_installed:
|
||||
# module placeholder
|
||||
def __getattr__(self, id):
|
||||
|
@ -95,10 +96,13 @@ except ImportError:
|
|||
builtins = __builtin__
|
||||
|
||||
from PIL import ImageMode
|
||||
from PIL._binary import i8, o8
|
||||
from PIL._util import isPath, isStringType, deferred_error
|
||||
from PIL._binary import i8
|
||||
from PIL._util import isPath
|
||||
from PIL._util import isStringType
|
||||
from PIL._util import deferred_error
|
||||
|
||||
import os, sys
|
||||
import os
|
||||
import sys
|
||||
|
||||
# type stuff
|
||||
import collections
|
||||
|
@ -112,6 +116,7 @@ try:
|
|||
except:
|
||||
HAS_CFFI = False
|
||||
|
||||
|
||||
def isImageType(t):
|
||||
"""
|
||||
Checks if an object is an image object.
|
||||
|
@ -252,6 +257,7 @@ _MODE_CONV = {
|
|||
"I;32LS": ('<i4', None),
|
||||
}
|
||||
|
||||
|
||||
def _conv_type_shape(im):
|
||||
shape = im.size[1], im.size[0]
|
||||
typ, extra = _MODE_CONV[im.mode]
|
||||
|
@ -383,6 +389,7 @@ def init():
|
|||
_initialized = 2
|
||||
return 1
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Codec factories (used by tobytes/frombytes and ImageFile.load)
|
||||
|
||||
|
@ -402,6 +409,7 @@ def _getdecoder(mode, decoder_name, args, extra=()):
|
|||
except AttributeError:
|
||||
raise IOError("decoder %s not available" % decoder_name)
|
||||
|
||||
|
||||
def _getencoder(mode, encoder_name, args, extra=()):
|
||||
|
||||
# tweak arguments
|
||||
|
@ -425,14 +433,18 @@ def _getencoder(mode, encoder_name, args, extra=()):
|
|||
def coerce_e(value):
|
||||
return value if isinstance(value, _E) else _E(value)
|
||||
|
||||
|
||||
class _E:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def __add__(self, other):
|
||||
return _E((self.data, "__add__", coerce_e(other).data))
|
||||
|
||||
def __mul__(self, other):
|
||||
return _E((self.data, "__mul__", coerce_e(other).data))
|
||||
|
||||
|
||||
def _getscaleoffset(expr):
|
||||
stub = ["stub"]
|
||||
data = expr(_E(stub)).data
|
||||
|
@ -442,13 +454,15 @@ def _getscaleoffset(expr):
|
|||
return c, 0.0
|
||||
if (a is stub and b == "__add__" and isinstance(c, numbers.Number)):
|
||||
return 1.0, c
|
||||
except TypeError: pass
|
||||
except TypeError:
|
||||
pass
|
||||
try:
|
||||
((a, b, c), d, e) = data # full syntax
|
||||
if (a is stub and b == "__mul__" and isinstance(c, numbers.Number) and
|
||||
d == "__add__" and isinstance(e, numbers.Number)):
|
||||
return c, e
|
||||
except TypeError: pass
|
||||
except TypeError:
|
||||
pass
|
||||
raise ValueError("illegal expression")
|
||||
|
||||
|
||||
|
@ -504,6 +518,7 @@ class Image:
|
|||
# Context Manager Support
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.close()
|
||||
|
||||
|
@ -529,7 +544,6 @@ class Image:
|
|||
# object is gone.
|
||||
self.im = deferred_error(ValueError("Operation on closed image"))
|
||||
|
||||
|
||||
def _copy(self):
|
||||
self.load()
|
||||
self.im = self.im.copy()
|
||||
|
@ -537,7 +551,8 @@ class Image:
|
|||
self.readonly = 0
|
||||
|
||||
def _dump(self, file=None, format=None):
|
||||
import tempfile, os
|
||||
import os
|
||||
import tempfile
|
||||
suffix = ''
|
||||
if format:
|
||||
suffix = '.'+format
|
||||
|
@ -554,6 +569,20 @@ class Image:
|
|||
self.save(file, format)
|
||||
return file
|
||||
|
||||
def __eq__(self, other):
|
||||
a = (self.mode == other.mode)
|
||||
b = (self.size == other.size)
|
||||
c = (self.getpalette() == other.getpalette())
|
||||
d = (self.info == other.info)
|
||||
e = (self.category == other.category)
|
||||
f = (self.readonly == other.readonly)
|
||||
g = (self.tobytes() == other.tobytes())
|
||||
return a and b and c and d and e and f and g
|
||||
|
||||
def __ne__(self, other):
|
||||
eq = (self == other)
|
||||
return not eq
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s.%s image mode=%s size=%dx%d at 0x%X>" % (
|
||||
self.__class__.__module__, self.__class__.__name__,
|
||||
|
@ -572,6 +601,26 @@ class Image:
|
|||
return new
|
||||
raise AttributeError(name)
|
||||
|
||||
def __getstate__(self):
|
||||
return [
|
||||
self.info,
|
||||
self.mode,
|
||||
self.size,
|
||||
self.getpalette(),
|
||||
self.tobytes()]
|
||||
|
||||
def __setstate__(self, state):
|
||||
Image.__init__(self)
|
||||
self.tile = []
|
||||
info, mode, size, palette, data = state
|
||||
self.info = info
|
||||
self.mode = mode
|
||||
self.size = size
|
||||
self.im = core.new(mode, size)
|
||||
if mode in ("L", "P"):
|
||||
self.putpalette(palette)
|
||||
self.frombytes(data)
|
||||
|
||||
def tobytes(self, encoder_name="raw", *args):
|
||||
"""
|
||||
Return image as a bytes object
|
||||
|
@ -632,9 +681,11 @@ class Image:
|
|||
if self.mode != "1":
|
||||
raise ValueError("not a bitmap")
|
||||
data = self.tobytes("xbm")
|
||||
return b"".join([("#define %s_width %d\n" % (name, self.size[0])).encode('ascii'),
|
||||
return b"".join([
|
||||
("#define %s_width %d\n" % (name, self.size[0])).encode('ascii'),
|
||||
("#define %s_height %d\n" % (name, self.size[1])).encode('ascii'),
|
||||
("static char %s_bits[] = {\n" % name).encode('ascii'), data, b"};"])
|
||||
("static char %s_bits[] = {\n" % name).encode('ascii'), data, b"};"
|
||||
])
|
||||
|
||||
def frombytes(self, data, decoder_name="raw", *args):
|
||||
"""
|
||||
|
@ -667,7 +718,9 @@ class Image:
|
|||
|
||||
.. deprecated:: 2.0
|
||||
"""
|
||||
warnings.warn('fromstring() is deprecated. Please call frombytes() instead.', DeprecationWarning)
|
||||
warnings.warn(
|
||||
'fromstring() is deprecated. Please call frombytes() instead.',
|
||||
DeprecationWarning)
|
||||
return self.frombytes(*args, **kw)
|
||||
|
||||
def load(self):
|
||||
|
@ -778,7 +831,8 @@ class Image:
|
|||
trns = None
|
||||
delete_trns = False
|
||||
# transparency handling
|
||||
if "transparency" in self.info and self.info['transparency'] is not None:
|
||||
if "transparency" in self.info and \
|
||||
self.info['transparency'] is not None:
|
||||
if self.mode in ('L', 'RGB') and mode == 'RGBA':
|
||||
# Use transparent conversion to promote from transparent
|
||||
# color to an alpha channel.
|
||||
|
@ -807,6 +861,8 @@ class Image:
|
|||
trns_im = trns_im.convert('RGB')
|
||||
trns = trns_im.getpixel((0,0))
|
||||
|
||||
elif self.mode == 'P' and mode == 'RGBA':
|
||||
delete_trns = True
|
||||
|
||||
if mode == "P" and palette == ADAPTIVE:
|
||||
im = self.im.quantize(colors)
|
||||
|
@ -824,7 +880,8 @@ class Image:
|
|||
# if we can't make a transparent color, don't leave the old
|
||||
# transparency hanging around to mess us up.
|
||||
del(new.info['transparency'])
|
||||
warnings.warn("Couldn't allocate palette entry for transparency")
|
||||
warnings.warn("Couldn't allocate palette entry " +
|
||||
"for transparency")
|
||||
return new
|
||||
|
||||
# colorspace conversion
|
||||
|
@ -851,7 +908,8 @@ class Image:
|
|||
new_im.info['transparency'] = new_im.palette.getcolor(trns)
|
||||
except:
|
||||
del(new_im.info['transparency'])
|
||||
warnings.warn("Couldn't allocate palette entry for transparency")
|
||||
warnings.warn("Couldn't allocate palette entry " +
|
||||
"for transparency")
|
||||
else:
|
||||
new_im.info['transparency'] = trns
|
||||
return new_im
|
||||
|
@ -967,7 +1025,8 @@ class Image:
|
|||
if isinstance(filter, collections.Callable):
|
||||
filter = filter()
|
||||
if not hasattr(filter, "filter"):
|
||||
raise TypeError("filter argument should be ImageFilter.Filter instance or class")
|
||||
raise TypeError("filter argument should be ImageFilter.Filter " +
|
||||
"instance or class")
|
||||
|
||||
if self.im.bands == 1:
|
||||
return self._new(filter.filter(self.im))
|
||||
|
@ -1074,7 +1133,6 @@ class Image:
|
|||
self.load()
|
||||
return self.im.ptr
|
||||
|
||||
|
||||
def getpalette(self):
|
||||
"""
|
||||
Returns the image palette as a list.
|
||||
|
@ -1092,7 +1150,6 @@ class Image:
|
|||
except ValueError:
|
||||
return None # no palette
|
||||
|
||||
|
||||
def getpixel(self, xy):
|
||||
"""
|
||||
Returns the pixel value at a given position.
|
||||
|
@ -1213,7 +1270,8 @@ class Image:
|
|||
|
||||
if isImageType(box) and mask is None:
|
||||
# abbreviated paste(im, mask) syntax
|
||||
mask = box; box = None
|
||||
mask = box
|
||||
box = None
|
||||
|
||||
if box is None:
|
||||
# cover all of self
|
||||
|
@ -1475,7 +1533,7 @@ class Image:
|
|||
clockwise around its centre.
|
||||
|
||||
:param angle: In degrees counter clockwise.
|
||||
:param filter: An optional resampling filter. This can be
|
||||
:param resample: An optional resampling filter. This can be
|
||||
one of :py:attr:`PIL.Image.NEAREST` (use nearest neighbour),
|
||||
:py:attr:`PIL.Image.BILINEAR` (linear interpolation in a 2x2
|
||||
environment), or :py:attr:`PIL.Image.BICUBIC`
|
||||
|
@ -1496,6 +1554,7 @@ class Image:
|
|||
math.cos(angle), math.sin(angle), 0.0,
|
||||
-math.sin(angle), math.cos(angle), 0.0
|
||||
]
|
||||
|
||||
def transform(x, y, matrix=matrix):
|
||||
(a, b, c, d, e, f) = matrix
|
||||
return a*x + b*y + c, d*x + e*y + f
|
||||
|
@ -1671,7 +1730,7 @@ class Image:
|
|||
"""
|
||||
return 0
|
||||
|
||||
def thumbnail(self, size, resample=NEAREST):
|
||||
def thumbnail(self, size, resample=ANTIALIAS):
|
||||
"""
|
||||
Make this image into a thumbnail. This method modifies the
|
||||
image to contain a thumbnail version of itself, no larger than
|
||||
|
@ -1686,26 +1745,28 @@ class Image:
|
|||
important than quality.
|
||||
|
||||
Also note that this function modifies the :py:class:`~PIL.Image.Image`
|
||||
object in place. If you need to use the full resolution image as well, apply
|
||||
this method to a :py:meth:`~PIL.Image.Image.copy` of the original image.
|
||||
object in place. If you need to use the full resolution image as well,
|
||||
apply this method to a :py:meth:`~PIL.Image.Image.copy` of the original
|
||||
image.
|
||||
|
||||
:param size: Requested size.
|
||||
:param resample: Optional resampling filter. This can be one
|
||||
of :py:attr:`PIL.Image.NEAREST`, :py:attr:`PIL.Image.BILINEAR`,
|
||||
:py:attr:`PIL.Image.BICUBIC`, or :py:attr:`PIL.Image.ANTIALIAS`
|
||||
(best quality). If omitted, it defaults to
|
||||
:py:attr:`PIL.Image.NEAREST` (this will be changed to ANTIALIAS in a
|
||||
future version).
|
||||
:py:attr:`PIL.Image.ANTIALIAS`. (was :py:attr:`PIL.Image.NEAREST`
|
||||
prior to version 2.5.0)
|
||||
:returns: None
|
||||
"""
|
||||
|
||||
# FIXME: the default resampling filter will be changed
|
||||
# to ANTIALIAS in future versions
|
||||
|
||||
# preserve aspect ratio
|
||||
x, y = self.size
|
||||
if x > size[0]: y = int(max(y * size[0] / x, 1)); x = int(size[0])
|
||||
if y > size[1]: x = int(max(x * size[1] / y, 1)); y = int(size[1])
|
||||
if x > size[0]:
|
||||
y = int(max(y * size[0] / x, 1))
|
||||
x = int(size[0])
|
||||
if y > size[1]:
|
||||
x = int(max(x * size[1] / y, 1))
|
||||
y = int(size[1])
|
||||
size = x, y
|
||||
|
||||
if size == self.size:
|
||||
|
@ -1756,7 +1817,8 @@ class Image:
|
|||
"""
|
||||
|
||||
if self.mode == 'RGBA':
|
||||
return self.convert('RGBa').transform(size, method, data, resample, fill).convert('RGBA')
|
||||
return self.convert('RGBa').transform(
|
||||
size, method, data, resample, fill).convert('RGBA')
|
||||
|
||||
if isinstance(method, ImageTransformHandler):
|
||||
return method.transform(size, self, resample=resample, fill=fill)
|
||||
|
@ -1803,8 +1865,13 @@ class Image:
|
|||
elif method == QUAD:
|
||||
# quadrilateral warp. data specifies the four corners
|
||||
# given as NW, SW, SE, and NE.
|
||||
nw = data[0:2]; sw = data[2:4]; se = data[4:6]; ne = data[6:8]
|
||||
x0, y0 = nw; As = 1.0 / w; At = 1.0 / h
|
||||
nw = data[0:2]
|
||||
sw = data[2:4]
|
||||
se = data[4:6]
|
||||
ne = data[6:8]
|
||||
x0, y0 = nw
|
||||
As = 1.0 / w
|
||||
At = 1.0 / h
|
||||
data = (x0, (ne[0]-x0)*As, (sw[0]-x0)*At,
|
||||
(se[0]-sw[0]-ne[0]+x0)*As*At,
|
||||
y0, (ne[1]-y0)*As, (sw[1]-y0)*At,
|
||||
|
@ -1838,6 +1905,7 @@ class Image:
|
|||
im = self.im.transpose(method)
|
||||
return self._new(im)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Lazy operations
|
||||
|
||||
|
@ -1873,6 +1941,7 @@ class _ImageCrop(Image):
|
|||
# FIXME: future versions should optimize crop/paste
|
||||
# sequences!
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Abstract handlers.
|
||||
|
||||
|
@ -1880,10 +1949,12 @@ class ImagePointHandler:
|
|||
# used as a mixin by point transforms (for use with im.point)
|
||||
pass
|
||||
|
||||
|
||||
class ImageTransformHandler:
|
||||
# used as a mixin by geometry transforms (for use with im.transform)
|
||||
pass
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Factories
|
||||
|
||||
|
@ -1959,6 +2030,7 @@ def frombytes(mode, size, data, decoder_name="raw", *args):
|
|||
im.frombytes(data, decoder_name, args)
|
||||
return im
|
||||
|
||||
|
||||
def fromstring(*args, **kw):
|
||||
"""Deprecated alias to frombytes.
|
||||
|
||||
|
@ -2181,6 +2253,7 @@ def open(fp, mode="r"):
|
|||
raise IOError("cannot identify image file %r"
|
||||
% (filename if filename else fp))
|
||||
|
||||
|
||||
#
|
||||
# Image processing.
|
||||
|
||||
|
@ -2279,6 +2352,7 @@ def merge(mode, bands):
|
|||
im.putband(bands[i].im, i)
|
||||
return bands[0]._new(im)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Plugin registry
|
||||
|
||||
|
@ -2337,6 +2411,7 @@ def _show(image, **options):
|
|||
# override me, as necessary
|
||||
_showxv(image, **options)
|
||||
|
||||
|
||||
def _showxv(image, title=None, **options):
|
||||
from PIL import ImageShow
|
||||
ImageShow.show(image, title, **options)
|
||||
|
|
301
PIL/ImageCms.py
|
@ -1,19 +1,19 @@
|
|||
#
|
||||
# The Python Imaging Library.
|
||||
# $Id$
|
||||
#
|
||||
# optional color managment support, based on Kevin Cazabon's PyCMS
|
||||
# library.
|
||||
#
|
||||
# History:
|
||||
# 2009-03-08 fl Added to PIL.
|
||||
#
|
||||
# Copyright (C) 2002-2003 Kevin Cazabon
|
||||
# Copyright (c) 2009 by Fredrik Lundh
|
||||
#
|
||||
# See the README file for information on usage and redistribution. See
|
||||
# below for the original description.
|
||||
#
|
||||
"""
|
||||
The Python Imaging Library.
|
||||
$Id$
|
||||
|
||||
Optional color managment support, based on Kevin Cazabon's PyCMS
|
||||
library.
|
||||
|
||||
History:
|
||||
2009-03-08 fl Added to PIL.
|
||||
|
||||
Copyright (C) 2002-2003 Kevin Cazabon
|
||||
Copyright (c) 2009 by Fredrik Lundh
|
||||
|
||||
See the README file for information on usage and redistribution. See
|
||||
below for the original description.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
|
@ -66,7 +66,8 @@ pyCMS
|
|||
|
||||
Added try/except statements arount type() checks of
|
||||
potential CObjects... Python won't let you use type()
|
||||
on them, and raises a TypeError (stupid, if you ask me!)
|
||||
on them, and raises a TypeError (stupid, if you ask
|
||||
me!)
|
||||
|
||||
Added buildProofTransformFromOpenProfiles() function.
|
||||
Additional fixes in DLL, see DLL code for details.
|
||||
|
@ -89,8 +90,8 @@ try:
|
|||
except ImportError as ex:
|
||||
# Allow error import for doc purposes, but error out when accessing
|
||||
# anything in core.
|
||||
from _util import deferred_error
|
||||
_imagingcms = deferred_error(ex)
|
||||
from _util import import_err
|
||||
_imagingcms = import_err(ex)
|
||||
from PIL._util import isStringType
|
||||
|
||||
core = _imagingcms
|
||||
|
@ -115,7 +116,9 @@ FLAGS = {
|
|||
"MATRIXOUTPUT": 2,
|
||||
"MATRIXONLY": (1 | 2),
|
||||
"NOWHITEONWHITEFIXUP": 4, # Don't hot fix scum dot
|
||||
"NOPRELINEARIZATION": 16, # Don't create prelinearization tables on precalculated transforms (internal use)
|
||||
# Don't create prelinearization tables on precalculated transforms
|
||||
# (internal use):
|
||||
"NOPRELINEARIZATION": 16,
|
||||
"GUESSDEVICECLASS": 32, # Guess device class (for transform2devicelink)
|
||||
"NOTCACHE": 64, # Inhibit 1-pixel cache
|
||||
"NOTPRECALC": 256,
|
||||
|
@ -136,6 +139,7 @@ for flag in FLAGS.values():
|
|||
if isinstance(flag, int):
|
||||
_MAX_FLAG = _MAX_FLAG | flag
|
||||
|
||||
|
||||
# --------------------------------------------------------------------.
|
||||
# Experimental PIL-level API
|
||||
# --------------------------------------------------------------------.
|
||||
|
@ -165,14 +169,16 @@ class ImageCmsProfile:
|
|||
self.product_name = None
|
||||
self.product_info = None
|
||||
|
||||
|
||||
class ImageCmsTransform(Image.ImagePointHandler):
|
||||
|
||||
"""Transform. This can be used with the procedural API, or with the
|
||||
standard Image.point() method.
|
||||
"""
|
||||
|
||||
def __init__(self, input, output, input_mode, output_mode,
|
||||
intent=INTENT_PERCEPTUAL,
|
||||
proof=None, proof_intent=INTENT_ABSOLUTE_COLORIMETRIC, flags=0):
|
||||
intent=INTENT_PERCEPTUAL, proof=None,
|
||||
proof_intent=INTENT_ABSOLUTE_COLORIMETRIC, flags=0):
|
||||
if proof is None:
|
||||
self.transform = core.buildTransform(
|
||||
input.profile, output.profile,
|
||||
|
@ -198,16 +204,17 @@ class ImageCmsTransform(Image.ImagePointHandler):
|
|||
im.load()
|
||||
if imOut is None:
|
||||
imOut = Image.new(self.output_mode, im.size, None)
|
||||
result = self.transform.apply(im.im.id, imOut.im.id)
|
||||
self.transform.apply(im.im.id, imOut.im.id)
|
||||
return imOut
|
||||
|
||||
def apply_in_place(self, im):
|
||||
im.load()
|
||||
if im.mode != self.output_mode:
|
||||
raise ValueError("mode mismatch") # wrong output mode
|
||||
result = self.transform.apply(im.im.id, im.im.id)
|
||||
self.transform.apply(im.im.id, im.im.id)
|
||||
return im
|
||||
|
||||
|
||||
def get_display_profile(handle=None):
|
||||
""" (experimental) Fetches the profile for the current display device.
|
||||
:returns: None if the profile is not known.
|
||||
|
@ -229,15 +236,21 @@ def get_display_profile(handle=None):
|
|||
profile = get()
|
||||
return ImageCmsProfile(profile)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------.
|
||||
# pyCMS compatible layer
|
||||
# --------------------------------------------------------------------.
|
||||
|
||||
class PyCMSError(Exception):
|
||||
""" (pyCMS) Exception class. This is used for all errors in the pyCMS API. """
|
||||
|
||||
""" (pyCMS) Exception class.
|
||||
This is used for all errors in the pyCMS API. """
|
||||
pass
|
||||
|
||||
def profileToProfile(im, inputProfile, outputProfile, renderingIntent=INTENT_PERCEPTUAL, outputMode=None, inPlace=0, flags=0):
|
||||
|
||||
def profileToProfile(
|
||||
im, inputProfile, outputProfile, renderingIntent=INTENT_PERCEPTUAL,
|
||||
outputMode=None, inPlace=0, flags=0):
|
||||
"""
|
||||
(pyCMS) Applies an ICC transformation to a given image, mapping from
|
||||
inputProfile to outputProfile.
|
||||
|
@ -259,29 +272,33 @@ def profileToProfile(im, inputProfile, outputProfile, renderingIntent=INTENT_PER
|
|||
profiles, the input profile must handle RGB data, and the output
|
||||
profile must handle CMYK data.
|
||||
|
||||
:param im: An open PIL image object (i.e. Image.new(...) or Image.open(...), etc.)
|
||||
:param inputProfile: String, as a valid filename path to the ICC input profile
|
||||
you wish to use for this image, or a profile object
|
||||
:param im: An open PIL image object (i.e. Image.new(...) or
|
||||
Image.open(...), etc.)
|
||||
:param inputProfile: String, as a valid filename path to the ICC input
|
||||
profile you wish to use for this image, or a profile object
|
||||
:param outputProfile: String, as a valid filename path to the ICC output
|
||||
profile you wish to use for this image, or a profile object
|
||||
:param renderingIntent: Integer (0-3) specifying the rendering intent you wish
|
||||
to use for the transform
|
||||
:param renderingIntent: Integer (0-3) specifying the rendering intent you
|
||||
wish to use for the transform
|
||||
|
||||
INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
|
||||
INTENT_RELATIVE_COLORIMETRIC = 1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
|
||||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC = 3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
|
||||
see the pyCMS documentation for details on rendering intents and what they do.
|
||||
:param outputMode: A valid PIL mode for the output image (i.e. "RGB", "CMYK",
|
||||
etc.). Note: if rendering the image "inPlace", outputMode MUST be the
|
||||
same mode as the input, or omitted completely. If omitted, the outputMode
|
||||
will be the same as the mode of the input image (im.mode)
|
||||
:param inPlace: Boolean (1 = True, None or 0 = False). If True, the original
|
||||
image is modified in-place, and None is returned. If False (default), a
|
||||
new Image object is returned with the transform applied.
|
||||
see the pyCMS documentation for details on rendering intents and what
|
||||
they do.
|
||||
:param outputMode: A valid PIL mode for the output image (i.e. "RGB",
|
||||
"CMYK", etc.). Note: if rendering the image "inPlace", outputMode
|
||||
MUST be the same mode as the input, or omitted completely. If
|
||||
omitted, the outputMode will be the same as the mode of the input
|
||||
image (im.mode)
|
||||
:param inPlace: Boolean (1 = True, None or 0 = False). If True, the
|
||||
original image is modified in-place, and None is returned. If False
|
||||
(default), a new Image object is returned with the transform applied.
|
||||
:param flags: Integer (0-...) specifying additional flags
|
||||
:returns: Either None or a new PIL image object, depending on value of inPlace
|
||||
:returns: Either None or a new PIL image object, depending on value of
|
||||
inPlace
|
||||
:exception PyCMSError:
|
||||
"""
|
||||
|
||||
|
@ -292,7 +309,8 @@ def profileToProfile(im, inputProfile, outputProfile, renderingIntent=INTENT_PER
|
|||
raise PyCMSError("renderingIntent must be an integer between 0 and 3")
|
||||
|
||||
if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG):
|
||||
raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
raise PyCMSError(
|
||||
"flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
|
||||
try:
|
||||
if not isinstance(inputProfile, ImageCmsProfile):
|
||||
|
@ -300,7 +318,8 @@ def profileToProfile(im, inputProfile, outputProfile, renderingIntent=INTENT_PER
|
|||
if not isinstance(outputProfile, ImageCmsProfile):
|
||||
outputProfile = ImageCmsProfile(outputProfile)
|
||||
transform = ImageCmsTransform(
|
||||
inputProfile, outputProfile, im.mode, outputMode, renderingIntent, flags=flags
|
||||
inputProfile, outputProfile, im.mode, outputMode,
|
||||
renderingIntent, flags=flags
|
||||
)
|
||||
if inPlace:
|
||||
transform.apply_in_place(im)
|
||||
|
@ -323,8 +342,8 @@ def getOpenProfile(profileFilename):
|
|||
If profileFilename is not a vaild filename for an ICC profile, a PyCMSError
|
||||
will be raised.
|
||||
|
||||
:param profileFilename: String, as a valid filename path to the ICC profile you
|
||||
wish to open, or a file-like object.
|
||||
:param profileFilename: String, as a valid filename path to the ICC profile
|
||||
you wish to open, or a file-like object.
|
||||
:returns: A CmsProfile class object.
|
||||
:exception PyCMSError:
|
||||
"""
|
||||
|
@ -334,7 +353,10 @@ def getOpenProfile(profileFilename):
|
|||
except (IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
def buildTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, flags=0):
|
||||
|
||||
def buildTransform(
|
||||
inputProfile, outputProfile, inMode, outMode,
|
||||
renderingIntent=INTENT_PERCEPTUAL, flags=0):
|
||||
"""
|
||||
(pyCMS) Builds an ICC transform mapping from the inputProfile to the
|
||||
outputProfile. Use applyTransform to apply the transform to a given
|
||||
|
@ -367,14 +389,14 @@ def buildTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent
|
|||
manually overridden if you really want to, but I don't know of any
|
||||
time that would be of use, or would even work).
|
||||
|
||||
:param inputProfile: String, as a valid filename path to the ICC input profile
|
||||
you wish to use for this transform, or a profile object
|
||||
:param inputProfile: String, as a valid filename path to the ICC input
|
||||
profile you wish to use for this transform, or a profile object
|
||||
:param outputProfile: String, as a valid filename path to the ICC output
|
||||
profile you wish to use for this transform, or a profile object
|
||||
:param inMode: String, as a valid PIL mode that the appropriate profile also
|
||||
supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
:param outMode: String, as a valid PIL mode that the appropriate profile also
|
||||
supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
:param inMode: String, as a valid PIL mode that the appropriate profile
|
||||
also supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
:param outMode: String, as a valid PIL mode that the appropriate profile
|
||||
also supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
:param renderingIntent: Integer (0-3) specifying the rendering intent you
|
||||
wish to use for the transform
|
||||
|
||||
|
@ -383,7 +405,8 @@ def buildTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent
|
|||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC = 3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
|
||||
see the pyCMS documentation for details on rendering intents and what they do.
|
||||
see the pyCMS documentation for details on rendering intents and what
|
||||
they do.
|
||||
:param flags: Integer (0-...) specifying additional flags
|
||||
:returns: A CmsTransform class object.
|
||||
:exception PyCMSError:
|
||||
|
@ -393,18 +416,26 @@ def buildTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent
|
|||
raise PyCMSError("renderingIntent must be an integer between 0 and 3")
|
||||
|
||||
if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG):
|
||||
raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
raise PyCMSError(
|
||||
"flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
|
||||
try:
|
||||
if not isinstance(inputProfile, ImageCmsProfile):
|
||||
inputProfile = ImageCmsProfile(inputProfile)
|
||||
if not isinstance(outputProfile, ImageCmsProfile):
|
||||
outputProfile = ImageCmsProfile(outputProfile)
|
||||
return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags)
|
||||
return ImageCmsTransform(
|
||||
inputProfile, outputProfile, inMode, outMode,
|
||||
renderingIntent, flags=flags)
|
||||
except (IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMode, renderingIntent=INTENT_PERCEPTUAL, proofRenderingIntent=INTENT_ABSOLUTE_COLORIMETRIC, flags=FLAGS["SOFTPROOFING"]):
|
||||
|
||||
def buildProofTransform(
|
||||
inputProfile, outputProfile, proofProfile, inMode, outMode,
|
||||
renderingIntent=INTENT_PERCEPTUAL,
|
||||
proofRenderingIntent=INTENT_ABSOLUTE_COLORIMETRIC,
|
||||
flags=FLAGS["SOFTPROOFING"]):
|
||||
"""
|
||||
(pyCMS) Builds an ICC transform mapping from the inputProfile to the
|
||||
outputProfile, but tries to simulate the result that would be
|
||||
|
@ -443,17 +474,17 @@ def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMo
|
|||
when the simulated device has a much wider gamut than the output
|
||||
device, you may obtain marginal results.
|
||||
|
||||
:param inputProfile: String, as a valid filename path to the ICC input profile
|
||||
you wish to use for this transform, or a profile object
|
||||
:param inputProfile: String, as a valid filename path to the ICC input
|
||||
profile you wish to use for this transform, or a profile object
|
||||
:param outputProfile: String, as a valid filename path to the ICC output
|
||||
(monitor, usually) profile you wish to use for this transform, or a
|
||||
profile object
|
||||
:param proofProfile: String, as a valid filename path to the ICC proof profile
|
||||
you wish to use for this transform, or a profile object
|
||||
:param inMode: String, as a valid PIL mode that the appropriate profile also
|
||||
supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
:param outMode: String, as a valid PIL mode that the appropriate profile also
|
||||
supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
:param proofProfile: String, as a valid filename path to the ICC proof
|
||||
profile you wish to use for this transform, or a profile object
|
||||
:param inMode: String, as a valid PIL mode that the appropriate profile
|
||||
also supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
:param outMode: String, as a valid PIL mode that the appropriate profile
|
||||
also supports (i.e. "RGB", "RGBA", "CMYK", etc.)
|
||||
:param renderingIntent: Integer (0-3) specifying the rendering intent you
|
||||
wish to use for the input->proof (simulated) transform
|
||||
|
||||
|
@ -462,7 +493,8 @@ def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMo
|
|||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC = 3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
|
||||
see the pyCMS documentation for details on rendering intents and what they do.
|
||||
see the pyCMS documentation for details on rendering intents and what
|
||||
they do.
|
||||
:param proofRenderingIntent: Integer (0-3) specifying the rendering intent you
|
||||
wish to use for proof->output transform
|
||||
|
||||
|
@ -471,7 +503,8 @@ def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMo
|
|||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC = 3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
|
||||
see the pyCMS documentation for details on rendering intents and what they do.
|
||||
see the pyCMS documentation for details on rendering intents and what
|
||||
they do.
|
||||
:param flags: Integer (0-...) specifying additional flags
|
||||
:returns: A CmsTransform class object.
|
||||
:exception PyCMSError:
|
||||
|
@ -481,7 +514,8 @@ def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMo
|
|||
raise PyCMSError("renderingIntent must be an integer between 0 and 3")
|
||||
|
||||
if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG):
|
||||
raise PyCMSError("flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
raise PyCMSError(
|
||||
"flags must be an integer between 0 and %s" + _MAX_FLAG)
|
||||
|
||||
try:
|
||||
if not isinstance(inputProfile, ImageCmsProfile):
|
||||
|
@ -490,13 +524,16 @@ def buildProofTransform(inputProfile, outputProfile, proofProfile, inMode, outMo
|
|||
outputProfile = ImageCmsProfile(outputProfile)
|
||||
if not isinstance(proofProfile, ImageCmsProfile):
|
||||
proofProfile = ImageCmsProfile(proofProfile)
|
||||
return ImageCmsTransform(inputProfile, outputProfile, inMode, outMode, renderingIntent, proofProfile, proofRenderingIntent, flags)
|
||||
return ImageCmsTransform(
|
||||
inputProfile, outputProfile, inMode, outMode, renderingIntent,
|
||||
proofProfile, proofRenderingIntent, flags)
|
||||
except (IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
buildTransformFromOpenProfiles = buildTransform
|
||||
buildProofTransformFromOpenProfiles = buildProofTransform
|
||||
|
||||
|
||||
def applyTransform(im, transform, inPlace=0):
|
||||
"""
|
||||
(pyCMS) Applies a transform to a given image.
|
||||
|
@ -514,8 +551,8 @@ def applyTransform(im, transform, inPlace=0):
|
|||
is raised.
|
||||
|
||||
This function applies a pre-calculated transform (from
|
||||
ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles()) to an
|
||||
image. The transform can be used for multiple images, saving
|
||||
ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles())
|
||||
to an image. The transform can be used for multiple images, saving
|
||||
considerable calcuation time if doing the same conversion multiple times.
|
||||
|
||||
If you want to modify im in-place instead of receiving a new image as
|
||||
|
@ -528,10 +565,12 @@ def applyTransform(im, transform, inPlace=0):
|
|||
:param im: A PIL Image object, and im.mode must be the same as the inMode
|
||||
supported by the transform.
|
||||
:param transform: A valid CmsTransform class object
|
||||
:param inPlace: Bool (1 == True, 0 or None == False). If True, im is modified
|
||||
in place and None is returned, if False, a new Image object with the
|
||||
transform applied is returned (and im is not changed). The default is False.
|
||||
:returns: Either None, or a new PIL Image object, depending on the value of inPlace
|
||||
:param inPlace: Bool (1 == True, 0 or None == False). If True, im is
|
||||
modified in place and None is returned, if False, a new Image object
|
||||
with the transform applied is returned (and im is not changed). The
|
||||
default is False.
|
||||
:returns: Either None, or a new PIL Image object, depending on the value of
|
||||
inPlace
|
||||
:exception PyCMSError:
|
||||
"""
|
||||
|
||||
|
@ -546,6 +585,7 @@ def applyTransform(im, transform, inPlace=0):
|
|||
|
||||
return imOut
|
||||
|
||||
|
||||
def createProfile(colorSpace, colorTemp=-1):
|
||||
"""
|
||||
(pyCMS) Creates a profile.
|
||||
|
@ -562,30 +602,36 @@ def createProfile(colorSpace, colorTemp=-1):
|
|||
ImageCms.buildTransformFromOpenProfiles() to create a transform to apply
|
||||
to images.
|
||||
|
||||
:param colorSpace: String, the color space of the profile you wish to create.
|
||||
:param colorSpace: String, the color space of the profile you wish to
|
||||
create.
|
||||
Currently only "LAB", "XYZ", and "sRGB" are supported.
|
||||
:param colorTemp: Positive integer for the white point for the profile, in
|
||||
degrees Kelvin (i.e. 5000, 6500, 9600, etc.). The default is for D50
|
||||
illuminant if omitted (5000k). colorTemp is ONLY applied to LAB profiles,
|
||||
and is ignored for XYZ and sRGB.
|
||||
illuminant if omitted (5000k). colorTemp is ONLY applied to LAB
|
||||
profiles, and is ignored for XYZ and sRGB.
|
||||
:returns: A CmsProfile class object
|
||||
:exception PyCMSError:
|
||||
"""
|
||||
|
||||
if colorSpace not in ["LAB", "XYZ", "sRGB"]:
|
||||
raise PyCMSError("Color space not supported for on-the-fly profile creation (%s)" % colorSpace)
|
||||
raise PyCMSError(
|
||||
"Color space not supported for on-the-fly profile creation (%s)"
|
||||
% colorSpace)
|
||||
|
||||
if colorSpace == "LAB":
|
||||
try:
|
||||
colorTemp = float(colorTemp)
|
||||
except:
|
||||
raise PyCMSError("Color temperature must be numeric, \"%s\" not valid" % colorTemp)
|
||||
raise PyCMSError(
|
||||
"Color temperature must be numeric, \"%s\" not valid"
|
||||
% colorTemp)
|
||||
|
||||
try:
|
||||
return core.createProfile(colorSpace, colorTemp)
|
||||
except (TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
|
||||
def getProfileName(profile):
|
||||
"""
|
||||
|
||||
|
@ -600,10 +646,10 @@ def getProfileName(profile):
|
|||
profile was originally created. Sometimes this tag also contains
|
||||
additional information supplied by the creator.
|
||||
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the filename
|
||||
of an ICC profile.
|
||||
:returns: A string containing the internal name of the profile as stored in an
|
||||
ICC tag.
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
:returns: A string containing the internal name of the profile as stored
|
||||
in an ICC tag.
|
||||
:exception PyCMSError:
|
||||
"""
|
||||
|
||||
|
@ -627,6 +673,7 @@ def getProfileName(profile):
|
|||
except (AttributeError, IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
|
||||
def getProfileInfo(profile):
|
||||
"""
|
||||
(pyCMS) Gets the internal product information for the given profile.
|
||||
|
@ -641,10 +688,10 @@ def getProfileInfo(profile):
|
|||
info tag. This often contains details about the profile, and how it
|
||||
was created, as supplied by the creator.
|
||||
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the filename
|
||||
of an ICC profile.
|
||||
:returns: A string containing the internal profile information stored in an ICC
|
||||
tag.
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
:returns: A string containing the internal profile information stored in
|
||||
an ICC tag.
|
||||
:exception PyCMSError:
|
||||
"""
|
||||
|
||||
|
@ -652,7 +699,8 @@ def getProfileInfo(profile):
|
|||
if not isinstance(profile, ImageCmsProfile):
|
||||
profile = ImageCmsProfile(profile)
|
||||
# add an extra newline to preserve pyCMS compatibility
|
||||
# Python, not C. the white point bits weren't working well, so skipping.
|
||||
# Python, not C. the white point bits weren't working well,
|
||||
# so skipping.
|
||||
# // info was description \r\n\r\n copyright \r\n\r\n K007 tag \r\n\r\n whitepoint
|
||||
description = profile.profile.product_description
|
||||
cpright = profile.profile.product_copyright
|
||||
|
@ -679,10 +727,10 @@ def getProfileCopyright(profile):
|
|||
Use this function to obtain the information stored in the profile's
|
||||
copyright tag.
|
||||
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the filename
|
||||
of an ICC profile.
|
||||
:returns: A string containing the internal profile information stored in an ICC
|
||||
tag.
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
:returns: A string containing the internal profile information stored in
|
||||
an ICC tag.
|
||||
:exception PyCMSError:
|
||||
"""
|
||||
try:
|
||||
|
@ -693,6 +741,7 @@ def getProfileCopyright(profile):
|
|||
except (AttributeError, IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
|
||||
def getProfileManufacturer(profile):
|
||||
"""
|
||||
(pyCMS) Gets the manufacturer for the given profile.
|
||||
|
@ -700,16 +749,16 @@ def getProfileManufacturer(profile):
|
|||
If profile isn't a valid CmsProfile object or filename to a profile,
|
||||
a PyCMSError is raised.
|
||||
|
||||
If an error occurs while trying to obtain the manufacturer tag, a PyCMSError
|
||||
is raised
|
||||
If an error occurs while trying to obtain the manufacturer tag, a
|
||||
PyCMSError is raised
|
||||
|
||||
Use this function to obtain the information stored in the profile's
|
||||
manufacturer tag.
|
||||
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the filename
|
||||
of an ICC profile.
|
||||
:returns: A string containing the internal profile information stored in an ICC
|
||||
tag.
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
:returns: A string containing the internal profile information stored in
|
||||
an ICC tag.
|
||||
:exception PyCMSError:
|
||||
"""
|
||||
try:
|
||||
|
@ -720,6 +769,7 @@ def getProfileManufacturer(profile):
|
|||
except (AttributeError, IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
|
||||
def getProfileModel(profile):
|
||||
"""
|
||||
(pyCMS) Gets the model for the given profile.
|
||||
|
@ -733,10 +783,10 @@ def getProfileModel(profile):
|
|||
Use this function to obtain the information stored in the profile's
|
||||
model tag.
|
||||
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the filename
|
||||
of an ICC profile.
|
||||
:returns: A string containing the internal profile information stored in an ICC
|
||||
tag.
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
:returns: A string containing the internal profile information stored in
|
||||
an ICC tag.
|
||||
:exception PyCMSError:
|
||||
"""
|
||||
|
||||
|
@ -748,6 +798,7 @@ def getProfileModel(profile):
|
|||
except (AttributeError, IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
|
||||
def getProfileDescription(profile):
|
||||
"""
|
||||
(pyCMS) Gets the description for the given profile.
|
||||
|
@ -761,10 +812,10 @@ def getProfileDescription(profile):
|
|||
Use this function to obtain the information stored in the profile's
|
||||
description tag.
|
||||
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the filename
|
||||
of an ICC profile.
|
||||
:returns: A string containing the internal profile information stored in an ICC
|
||||
tag.
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
:returns: A string containing the internal profile information stored in an
|
||||
ICC tag.
|
||||
:exception PyCMSError:
|
||||
"""
|
||||
|
||||
|
@ -793,16 +844,18 @@ def getDefaultIntent(profile):
|
|||
If you wish to use a different intent than returned, use
|
||||
ImageCms.isIntentSupported() to verify it will work first.
|
||||
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the filename
|
||||
of an ICC profile.
|
||||
:returns: Integer 0-3 specifying the default rendering intent for this profile.
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
:returns: Integer 0-3 specifying the default rendering intent for this
|
||||
profile.
|
||||
|
||||
INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
|
||||
INTENT_RELATIVE_COLORIMETRIC = 1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
|
||||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC = 3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
|
||||
see the pyCMS documentation for details on rendering intents and what they do.
|
||||
see the pyCMS documentation for details on rendering intents and what
|
||||
they do.
|
||||
:exception PyCMSError:
|
||||
"""
|
||||
|
||||
|
@ -813,6 +866,7 @@ def getDefaultIntent(profile):
|
|||
except (AttributeError, IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
|
||||
def isIntentSupported(profile, intent, direction):
|
||||
"""
|
||||
(pyCMS) Checks if a given intent is supported.
|
||||
|
@ -828,17 +882,18 @@ def isIntentSupported(profile, intent, direction):
|
|||
potential PyCMSError that will occur if they don't support the modes
|
||||
you select.
|
||||
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the filename
|
||||
of an ICC profile.
|
||||
:param intent: Integer (0-3) specifying the rendering intent you wish to use
|
||||
with this profile
|
||||
:param profile: EITHER a valid CmsProfile object, OR a string of the
|
||||
filename of an ICC profile.
|
||||
:param intent: Integer (0-3) specifying the rendering intent you wish to
|
||||
use with this profile
|
||||
|
||||
INTENT_PERCEPTUAL = 0 (DEFAULT) (ImageCms.INTENT_PERCEPTUAL)
|
||||
INTENT_RELATIVE_COLORIMETRIC = 1 (ImageCms.INTENT_RELATIVE_COLORIMETRIC)
|
||||
INTENT_SATURATION = 2 (ImageCms.INTENT_SATURATION)
|
||||
INTENT_ABSOLUTE_COLORIMETRIC = 3 (ImageCms.INTENT_ABSOLUTE_COLORIMETRIC)
|
||||
|
||||
see the pyCMS documentation for details on rendering intents and what they do.
|
||||
see the pyCMS documentation for details on rendering intents and what
|
||||
they do.
|
||||
:param direction: Integer specifing if the profile is to be used for input,
|
||||
output, or proof
|
||||
|
||||
|
@ -862,6 +917,7 @@ def isIntentSupported(profile, intent, direction):
|
|||
except (AttributeError, IOError, TypeError, ValueError) as v:
|
||||
raise PyCMSError(v)
|
||||
|
||||
|
||||
def versions():
|
||||
"""
|
||||
(pyCMS) Fetches versions.
|
||||
|
@ -869,7 +925,8 @@ def versions():
|
|||
|
||||
import sys
|
||||
return (
|
||||
VERSION, core.littlecms_version, sys.version.split()[0], Image.VERSION
|
||||
VERSION, core.littlecms_version,
|
||||
sys.version.split()[0], Image.VERSION
|
||||
)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
@ -880,14 +937,16 @@ if __name__ == "__main__":
|
|||
from PIL import ImageCms
|
||||
print(__doc__)
|
||||
|
||||
for f in dir(pyCMS):
|
||||
print("="*80)
|
||||
print("%s" %f)
|
||||
|
||||
for f in dir(ImageCms):
|
||||
doc = None
|
||||
try:
|
||||
exec ("doc = ImageCms.%s.__doc__" %(f))
|
||||
exec("doc = %s.__doc__" % (f))
|
||||
if "pyCMS" in doc:
|
||||
# so we don't get the __doc__ string for imported modules
|
||||
print("=" * 80)
|
||||
print("%s" % f)
|
||||
print(doc)
|
||||
except AttributeError:
|
||||
except (AttributeError, TypeError):
|
||||
pass
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#
|
||||
# For a background, see "Image Processing By Interpolation and
|
||||
# Extrapolation", Paul Haeberli and Douglas Voorhies. Available
|
||||
# at http://www.sgi.com/grafica/interp/index.html
|
||||
# at http://www.graficaobscura.com/interp/index.html
|
||||
#
|
||||
# History:
|
||||
# 1996-03-23 fl Created
|
||||
|
|
|
@ -15,11 +15,12 @@
|
|||
|
||||
__version__ = "0.1"
|
||||
|
||||
from PIL import Image, ImageFile, _binary
|
||||
from PIL import Image, ImageFile
|
||||
import struct
|
||||
import os
|
||||
import io
|
||||
|
||||
|
||||
def _parse_codestream(fp):
|
||||
"""Parse the JPEG 2000 codestream to extract the size and component
|
||||
count from the SIZ marker segment, returning a PIL (size, mode) tuple."""
|
||||
|
@ -51,6 +52,7 @@ def _parse_codestream(fp):
|
|||
|
||||
return (size, mode)
|
||||
|
||||
|
||||
def _parse_jp2_header(fp):
|
||||
"""Parse the JP2 header box to extract size, component count and
|
||||
color space information, returning a PIL (size, mode) tuple."""
|
||||
|
@ -127,6 +129,7 @@ def _parse_jp2_header(fp):
|
|||
|
||||
return (size, mode)
|
||||
|
||||
|
||||
##
|
||||
# Image plugin for JPEG2000 images.
|
||||
|
||||
|
@ -155,15 +158,25 @@ class Jpeg2KImageFile(ImageFile.ImageFile):
|
|||
self.layers = 0
|
||||
|
||||
fd = -1
|
||||
length = -1
|
||||
|
||||
if hasattr(self.fp, "fileno"):
|
||||
try:
|
||||
fd = self.fp.fileno()
|
||||
length = os.fstat(fd).st_size
|
||||
except:
|
||||
fd = -1
|
||||
elif hasattr(self.fp, "seek"):
|
||||
try:
|
||||
pos = f.tell()
|
||||
f.seek(0, 2)
|
||||
length = f.tell()
|
||||
f.seek(pos, 0)
|
||||
except:
|
||||
length = -1
|
||||
|
||||
self.tile = [('jpeg2k', (0, 0) + self.size, 0,
|
||||
(self.codec, self.reduce, self.layers, fd))]
|
||||
(self.codec, self.reduce, self.layers, fd, length))]
|
||||
|
||||
def load(self):
|
||||
if self.reduce:
|
||||
|
@ -175,15 +188,17 @@ class Jpeg2KImageFile(ImageFile.ImageFile):
|
|||
if self.tile:
|
||||
# Update the reduce and layers settings
|
||||
t = self.tile[0]
|
||||
t3 = (t[3][0], self.reduce, self.layers, t[3][3])
|
||||
t3 = (t[3][0], self.reduce, self.layers, t[3][3], t[3][4])
|
||||
self.tile = [(t[0], (0, 0) + self.size, t[2], t3)]
|
||||
|
||||
ImageFile.ImageFile.load(self)
|
||||
|
||||
|
||||
def _accept(prefix):
|
||||
return (prefix[:4] == b'\xff\x4f\xff\x51'
|
||||
or prefix[:12] == b'\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a')
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Save support
|
||||
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
|
||||
__version__ = "0.6"
|
||||
|
||||
import array, struct
|
||||
import array
|
||||
import struct
|
||||
from PIL import Image, ImageFile, _binary
|
||||
from PIL.JpegPresets import presets
|
||||
from PIL._util import isStringType
|
||||
|
@ -44,6 +45,7 @@ o8 = _binary.o8
|
|||
i16 = _binary.i16be
|
||||
i32 = _binary.i32be
|
||||
|
||||
|
||||
#
|
||||
# Parser
|
||||
|
||||
|
@ -51,6 +53,7 @@ def Skip(self, marker):
|
|||
n = i16(self.fp.read(2))-2
|
||||
ImageFile._safe_read(self.fp, n)
|
||||
|
||||
|
||||
def APP(self, marker):
|
||||
#
|
||||
# Application marker. Store these in the APP dictionary.
|
||||
|
@ -108,16 +111,17 @@ def APP(self, marker):
|
|||
else:
|
||||
self.info["adobe_transform"] = adobe_transform
|
||||
|
||||
|
||||
def COM(self, marker):
|
||||
#
|
||||
# Comment marker. Store these in the APP dictionary.
|
||||
|
||||
n = i16(self.fp.read(2))-2
|
||||
s = ImageFile._safe_read(self.fp, n)
|
||||
|
||||
self.app["COM"] = s # compatibility
|
||||
self.applist.append(("COM", s))
|
||||
|
||||
|
||||
def SOF(self, marker):
|
||||
#
|
||||
# Start of frame marker. Defines the size and mode of the
|
||||
|
@ -165,6 +169,7 @@ def SOF(self, marker):
|
|||
# 4-tuples: id, vsamp, hsamp, qtable
|
||||
self.layer.append((t[0], i8(t[1])//16, i8(t[1]) & 15, i8(t[2])))
|
||||
|
||||
|
||||
def DQT(self, marker):
|
||||
#
|
||||
# Define quantization table. Support baseline 8-bit tables
|
||||
|
@ -261,6 +266,7 @@ MARKER = {
|
|||
def _accept(prefix):
|
||||
return prefix[0:1] == b"\377"
|
||||
|
||||
|
||||
##
|
||||
# Image plugin for JPEG and JFIF images.
|
||||
|
||||
|
@ -290,9 +296,14 @@ class JpegImageFile(ImageFile.ImageFile):
|
|||
|
||||
while True:
|
||||
|
||||
i = i8(s)
|
||||
if i == 0xFF:
|
||||
s = s + self.fp.read(1)
|
||||
|
||||
i = i16(s)
|
||||
else:
|
||||
# Skip non-0xFF junk
|
||||
s = b"\xff"
|
||||
continue
|
||||
|
||||
if i in MARKER:
|
||||
name, description, handler = MARKER[i]
|
||||
|
@ -307,9 +318,9 @@ class JpegImageFile(ImageFile.ImageFile):
|
|||
# self.__offset = self.fp.tell()
|
||||
break
|
||||
s = self.fp.read(1)
|
||||
elif i == 0 or i == 65535:
|
||||
elif i == 0 or i == 0xFFFF:
|
||||
# padded marker or junk; move on
|
||||
s = "\xff"
|
||||
s = b"\xff"
|
||||
else:
|
||||
raise SyntaxError("no marker found")
|
||||
|
||||
|
@ -343,7 +354,8 @@ class JpegImageFile(ImageFile.ImageFile):
|
|||
|
||||
# ALTERNATIVE: handle JPEGs via the IJG command line utilities
|
||||
|
||||
import tempfile, os
|
||||
import tempfile
|
||||
import os
|
||||
f, path = tempfile.mkstemp()
|
||||
os.close(f)
|
||||
if os.path.exists(self.filename):
|
||||
|
@ -354,8 +366,10 @@ class JpegImageFile(ImageFile.ImageFile):
|
|||
try:
|
||||
self.im = Image.core.open_ppm(path)
|
||||
finally:
|
||||
try: os.unlink(path)
|
||||
except: pass
|
||||
try:
|
||||
os.unlink(path)
|
||||
except:
|
||||
pass
|
||||
|
||||
self.mode = self.im.mode
|
||||
self.size = self.im.size
|
||||
|
@ -372,6 +386,7 @@ def _getexif(self):
|
|||
# version.
|
||||
from PIL import TiffImagePlugin
|
||||
import io
|
||||
|
||||
def fixup(value):
|
||||
if len(value) == 1:
|
||||
return value[0]
|
||||
|
@ -441,16 +456,19 @@ samplings = {
|
|||
(2, 2, 1, 1, 1, 1): 2,
|
||||
}
|
||||
|
||||
|
||||
def convert_dict_qtables(qtables):
|
||||
qtables = [qtables[key] for key in range(len(qtables)) if key in qtables]
|
||||
for idx, table in enumerate(qtables):
|
||||
qtables[idx] = [table[i] for i in zigzag_index]
|
||||
return qtables
|
||||
|
||||
|
||||
def get_sampling(im):
|
||||
sampling = im.layer[0][1:3] + im.layer[1][1:3] + im.layer[2][1:3]
|
||||
return samplings.get(sampling, -1)
|
||||
|
||||
|
||||
def _save(im, fp, filename):
|
||||
|
||||
try:
|
||||
|
@ -563,10 +581,9 @@ def _save(im, fp, filename):
|
|||
info.get("exif", b"")
|
||||
)
|
||||
|
||||
|
||||
# if we optimize, libjpeg needs a buffer big enough to hold the whole image in a shot.
|
||||
# Guessing on the size, at im.size bytes. (raw pizel size is channels*size, this
|
||||
# is a value that's been used in a django patch.
|
||||
# if we optimize, libjpeg needs a buffer big enough to hold the whole image
|
||||
# in a shot. Guessing on the size, at im.size bytes. (raw pizel size is
|
||||
# channels*size, this is a value that's been used in a django patch.
|
||||
# https://github.com/jdriscoll/django-imagekit/issues/50
|
||||
bufsize = 0
|
||||
if "optimize" in info or "progressive" in info or "progression" in info:
|
||||
|
@ -581,13 +598,16 @@ def _save(im, fp, filename):
|
|||
|
||||
ImageFile._save(im, fp, [("jpeg", (0, 0)+im.size, 0, rawmode)], bufsize)
|
||||
|
||||
|
||||
def _save_cjpeg(im, fp, filename):
|
||||
# ALTERNATIVE: handle JPEGs via the IJG command line utilities.
|
||||
import os
|
||||
file = im._dump()
|
||||
os.system("cjpeg %s >%s" % (file, filename))
|
||||
try: os.unlink(file)
|
||||
except: pass
|
||||
try:
|
||||
os.unlink(file)
|
||||
except:
|
||||
pass
|
||||
|
||||
# -------------------------------------------------------------------q-
|
||||
# Registry stuff
|
||||
|
|
|
@ -7,7 +7,7 @@ This is an improved version of the OleFileIO module from [PIL](http://www.python
|
|||
|
||||
As far as I know, this module is now the most complete and robust Python implementation to read MS OLE2 files, portable on several operating systems. (please tell me if you know other similar Python modules)
|
||||
|
||||
OleFileIO_PL can be used as an independent module or with PIL. The goal is to have it integrated into [Pillow](http://python-imaging.github.io/), the friendly fork of PIL.
|
||||
OleFileIO_PL can be used as an independent module or with PIL. The goal is to have it integrated into [Pillow](http://python-pillow.github.io/), the friendly fork of PIL.
|
||||
|
||||
OleFileIO\_PL is mostly meant for developers. If you are looking for tools to analyze OLE files or to extract data, then please also check [python-oletools](http://www.decalage.info/python/oletools), which are built upon OleFileIO_PL.
|
||||
|
||||
|
|
|
@ -46,9 +46,11 @@ def _obj(fp, obj, **dict):
|
|||
fp.write("/%s %s\n" % (k, v))
|
||||
fp.write(">>\n")
|
||||
|
||||
|
||||
def _endobj(fp):
|
||||
fp.write("endobj\n")
|
||||
|
||||
|
||||
##
|
||||
# (Internal) Image save plugin for the PDF format.
|
||||
|
||||
|
@ -64,8 +66,10 @@ def _save(im, fp, filename):
|
|||
class TextWriter:
|
||||
def __init__(self, fp):
|
||||
self.fp = fp
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.fp, name)
|
||||
|
||||
def write(self, value):
|
||||
self.fp.write(value.encode('latin-1'))
|
||||
|
||||
|
@ -105,7 +109,7 @@ def _save(im, fp, filename):
|
|||
g = i8(palette[i*3+1])
|
||||
b = i8(palette[i*3+2])
|
||||
colorspace = colorspace + "%02x%02x%02x " % (r, g, b)
|
||||
colorspace = colorspace + b"> ]"
|
||||
colorspace = colorspace + "> ]"
|
||||
procset = "/ImageI" # indexed color
|
||||
elif im.mode == "RGB":
|
||||
filter = "/DCTDecode"
|
||||
|
@ -122,7 +126,9 @@ def _save(im, fp, filename):
|
|||
# catalogue
|
||||
|
||||
xref[1] = fp.tell()
|
||||
_obj(fp, 1, Type = "/Catalog",
|
||||
_obj(
|
||||
fp, 1,
|
||||
Type="/Catalog",
|
||||
Pages="2 0 R")
|
||||
_endobj(fp)
|
||||
|
||||
|
@ -130,7 +136,9 @@ def _save(im, fp, filename):
|
|||
# pages
|
||||
|
||||
xref[2] = fp.tell()
|
||||
_obj(fp, 2, Type = "/Pages",
|
||||
_obj(
|
||||
fp, 2,
|
||||
Type="/Pages",
|
||||
Count=1,
|
||||
Kids="[4 0 R]")
|
||||
_endobj(fp)
|
||||
|
@ -144,7 +152,7 @@ def _save(im, fp, filename):
|
|||
if bits == 1:
|
||||
# FIXME: the hex encoder doesn't support packed 1-bit
|
||||
# images; do things the hard way...
|
||||
data = im.tostring("raw", "1")
|
||||
data = im.tobytes("raw", "1")
|
||||
im = Image.new("L", (len(data), 1), None)
|
||||
im.putdata(data)
|
||||
ImageFile._save(im, op, [("hex", (0, 0)+im.size, 0, im.mode)])
|
||||
|
@ -158,7 +166,9 @@ def _save(im, fp, filename):
|
|||
raise ValueError("unsupported PDF filter (%s)" % filter)
|
||||
|
||||
xref[3] = fp.tell()
|
||||
_obj(fp, 3, Type = "/XObject",
|
||||
_obj(
|
||||
fp, 3,
|
||||
Type="/XObject",
|
||||
Subtype="/Image",
|
||||
Width=width, # * 72.0 / resolution,
|
||||
Height=height, # * 72.0 / resolution,
|
||||
|
@ -179,11 +189,14 @@ def _save(im, fp, filename):
|
|||
|
||||
xref[4] = fp.tell()
|
||||
_obj(fp, 4)
|
||||
fp.write("<<\n/Type /Page\n/Parent 2 0 R\n"\
|
||||
"/Resources <<\n/ProcSet [ /PDF %s ]\n"\
|
||||
"/XObject << /image 3 0 R >>\n>>\n"\
|
||||
"/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" %\
|
||||
(procset, int(width * 72.0 /resolution) , int(height * 72.0 / resolution)))
|
||||
fp.write(
|
||||
"<<\n/Type /Page\n/Parent 2 0 R\n"
|
||||
"/Resources <<\n/ProcSet [ /PDF %s ]\n"
|
||||
"/XObject << /image 3 0 R >>\n>>\n"
|
||||
"/MediaBox [ 0 0 %d %d ]\n/Contents 5 0 R\n>>\n" % (
|
||||
procset,
|
||||
int(width * 72.0 / resolution),
|
||||
int(height * 72.0 / resolution)))
|
||||
_endobj(fp)
|
||||
|
||||
#
|
||||
|
@ -191,7 +204,10 @@ def _save(im, fp, filename):
|
|||
|
||||
op = TextWriter(io.BytesIO())
|
||||
|
||||
op.write("q %d 0 0 %d 0 0 cm /image Do Q\n" % (int(width * 72.0 / resolution), int(height * 72.0 / resolution)))
|
||||
op.write(
|
||||
"q %d 0 0 %d 0 0 cm /image Do Q\n" % (
|
||||
int(width * 72.0 / resolution),
|
||||
int(height * 72.0 / resolution)))
|
||||
|
||||
xref[5] = fp.tell()
|
||||
_obj(fp, 5, Length=len(op.fp.getvalue()))
|
||||
|
|
|
@ -89,33 +89,33 @@ class ChunkStream:
|
|||
"Fetch a new chunk. Returns header information."
|
||||
|
||||
if self.queue:
|
||||
cid, pos, len = self.queue[-1]
|
||||
cid, pos, length = self.queue[-1]
|
||||
del self.queue[-1]
|
||||
self.fp.seek(pos)
|
||||
else:
|
||||
s = self.fp.read(8)
|
||||
cid = s[4:]
|
||||
pos = self.fp.tell()
|
||||
len = i32(s)
|
||||
length = i32(s)
|
||||
|
||||
if not is_cid(cid):
|
||||
raise SyntaxError("broken PNG file (chunk %s)" % repr(cid))
|
||||
|
||||
return cid, pos, len
|
||||
return cid, pos, length
|
||||
|
||||
def close(self):
|
||||
self.queue = self.crc = self.fp = None
|
||||
|
||||
def push(self, cid, pos, len):
|
||||
def push(self, cid, pos, length):
|
||||
|
||||
self.queue.append((cid, pos, len))
|
||||
self.queue.append((cid, pos, length))
|
||||
|
||||
def call(self, cid, pos, len):
|
||||
def call(self, cid, pos, length):
|
||||
"Call the appropriate chunk handler"
|
||||
|
||||
if Image.DEBUG:
|
||||
print("STREAM", cid, pos, len)
|
||||
return getattr(self, "chunk_" + cid.decode('ascii'))(pos, len)
|
||||
print("STREAM", cid, pos, length)
|
||||
return getattr(self, "chunk_" + cid.decode('ascii'))(pos, length)
|
||||
|
||||
def crc(self, cid, data):
|
||||
"Read and verify checksum"
|
||||
|
@ -139,10 +139,10 @@ class ChunkStream:
|
|||
cids = []
|
||||
|
||||
while True:
|
||||
cid, pos, len = self.read()
|
||||
cid, pos, length = self.read()
|
||||
if cid == endchunk:
|
||||
break
|
||||
self.crc(cid, ImageFile._safe_read(self.fp, len))
|
||||
self.crc(cid, ImageFile._safe_read(self.fp, length))
|
||||
cids.append(cid)
|
||||
|
||||
return cids
|
||||
|
@ -190,10 +190,10 @@ class PngStream(ChunkStream):
|
|||
self.im_tile = None
|
||||
self.im_palette = None
|
||||
|
||||
def chunk_iCCP(self, pos, len):
|
||||
def chunk_iCCP(self, pos, length):
|
||||
|
||||
# ICC profile
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
s = ImageFile._safe_read(self.fp, length)
|
||||
# according to PNG spec, the iCCP chunk contains:
|
||||
# Profile name 1-79 bytes (character string)
|
||||
# Null separator 1 byte (null character)
|
||||
|
@ -213,10 +213,10 @@ class PngStream(ChunkStream):
|
|||
self.im_info["icc_profile"] = icc_profile
|
||||
return s
|
||||
|
||||
def chunk_IHDR(self, pos, len):
|
||||
def chunk_IHDR(self, pos, length):
|
||||
|
||||
# image header
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
s = ImageFile._safe_read(self.fp, length)
|
||||
self.im_size = i32(s), i32(s[4:])
|
||||
try:
|
||||
self.im_mode, self.im_rawmode = _MODES[(i8(s[8]), i8(s[9]))]
|
||||
|
@ -228,30 +228,30 @@ class PngStream(ChunkStream):
|
|||
raise SyntaxError("unknown filter category")
|
||||
return s
|
||||
|
||||
def chunk_IDAT(self, pos, len):
|
||||
def chunk_IDAT(self, pos, length):
|
||||
|
||||
# image data
|
||||
self.im_tile = [("zip", (0,0)+self.im_size, pos, self.im_rawmode)]
|
||||
self.im_idat = len
|
||||
self.im_idat = length
|
||||
raise EOFError
|
||||
|
||||
def chunk_IEND(self, pos, len):
|
||||
def chunk_IEND(self, pos, length):
|
||||
|
||||
# end of PNG image
|
||||
raise EOFError
|
||||
|
||||
def chunk_PLTE(self, pos, len):
|
||||
def chunk_PLTE(self, pos, length):
|
||||
|
||||
# palette
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
s = ImageFile._safe_read(self.fp, length)
|
||||
if self.im_mode == "P":
|
||||
self.im_palette = "RGB", s
|
||||
return s
|
||||
|
||||
def chunk_tRNS(self, pos, len):
|
||||
def chunk_tRNS(self, pos, length):
|
||||
|
||||
# transparency
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
s = ImageFile._safe_read(self.fp, length)
|
||||
if self.im_mode == "P":
|
||||
if _simple_palette.match(s):
|
||||
i = s.find(b"\0")
|
||||
|
@ -265,17 +265,17 @@ class PngStream(ChunkStream):
|
|||
self.im_info["transparency"] = i16(s), i16(s[2:]), i16(s[4:])
|
||||
return s
|
||||
|
||||
def chunk_gAMA(self, pos, len):
|
||||
def chunk_gAMA(self, pos, length):
|
||||
|
||||
# gamma setting
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
s = ImageFile._safe_read(self.fp, length)
|
||||
self.im_info["gamma"] = i32(s) / 100000.0
|
||||
return s
|
||||
|
||||
def chunk_pHYs(self, pos, len):
|
||||
def chunk_pHYs(self, pos, length):
|
||||
|
||||
# pixels per unit
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
s = ImageFile._safe_read(self.fp, length)
|
||||
px, py = i32(s), i32(s[4:])
|
||||
unit = i8(s[8])
|
||||
if unit == 1: # meter
|
||||
|
@ -285,10 +285,10 @@ class PngStream(ChunkStream):
|
|||
self.im_info["aspect"] = px, py
|
||||
return s
|
||||
|
||||
def chunk_tEXt(self, pos, len):
|
||||
def chunk_tEXt(self, pos, length):
|
||||
|
||||
# text
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
s = ImageFile._safe_read(self.fp, length)
|
||||
try:
|
||||
k, v = s.split(b"\0", 1)
|
||||
except ValueError:
|
||||
|
@ -301,10 +301,10 @@ class PngStream(ChunkStream):
|
|||
self.im_info[k] = self.im_text[k] = v
|
||||
return s
|
||||
|
||||
def chunk_zTXt(self, pos, len):
|
||||
def chunk_zTXt(self, pos, length):
|
||||
|
||||
# compressed text
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
s = ImageFile._safe_read(self.fp, length)
|
||||
try:
|
||||
k, v = s.split(b"\0", 1)
|
||||
except ValueError:
|
||||
|
@ -358,16 +358,16 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
#
|
||||
# get next chunk
|
||||
|
||||
cid, pos, len = self.png.read()
|
||||
cid, pos, length = self.png.read()
|
||||
|
||||
try:
|
||||
s = self.png.call(cid, pos, len)
|
||||
s = self.png.call(cid, pos, length)
|
||||
except EOFError:
|
||||
break
|
||||
except AttributeError:
|
||||
if Image.DEBUG:
|
||||
print(cid, pos, len, "(unknown)")
|
||||
s = ImageFile._safe_read(self.fp, len)
|
||||
print(cid, pos, length, "(unknown)")
|
||||
s = ImageFile._safe_read(self.fp, length)
|
||||
|
||||
self.png.crc(cid, s)
|
||||
|
||||
|
@ -388,7 +388,7 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
rawmode, data = self.png.im_palette
|
||||
self.palette = ImagePalette.raw(rawmode, data)
|
||||
|
||||
self.__idat = len # used by load_read()
|
||||
self.__idat = length # used by load_read()
|
||||
|
||||
|
||||
def verify(self):
|
||||
|
@ -413,7 +413,7 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
|
||||
ImageFile.ImageFile.load_prepare(self)
|
||||
|
||||
def load_read(self, bytes):
|
||||
def load_read(self, read_bytes):
|
||||
"internal: read more image data"
|
||||
|
||||
while self.__idat == 0:
|
||||
|
@ -421,23 +421,23 @@ class PngImageFile(ImageFile.ImageFile):
|
|||
|
||||
self.fp.read(4) # CRC
|
||||
|
||||
cid, pos, len = self.png.read()
|
||||
cid, pos, length = self.png.read()
|
||||
|
||||
if cid not in [b"IDAT", b"DDAT"]:
|
||||
self.png.push(cid, pos, len)
|
||||
self.png.push(cid, pos, length)
|
||||
return b""
|
||||
|
||||
self.__idat = len # empty chunks are allowed
|
||||
self.__idat = length # empty chunks are allowed
|
||||
|
||||
# read more data from this chunk
|
||||
if bytes <= 0:
|
||||
bytes = self.__idat
|
||||
if read_bytes <= 0:
|
||||
read_bytes = self.__idat
|
||||
else:
|
||||
bytes = min(bytes, self.__idat)
|
||||
read_bytes = min(read_bytes, self.__idat)
|
||||
|
||||
self.__idat = self.__idat - bytes
|
||||
self.__idat = self.__idat - read_bytes
|
||||
|
||||
return self.fp.read(bytes)
|
||||
return self.fp.read(read_bytes)
|
||||
|
||||
|
||||
def load_end(self):
|
||||
|
|
|
@ -36,18 +36,24 @@
|
|||
from __future__ import print_function
|
||||
|
||||
from PIL import Image, ImageFile
|
||||
import os, struct, sys
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
|
||||
|
||||
def isInt(f):
|
||||
try:
|
||||
i = int(f)
|
||||
if f-i == 0: return 1
|
||||
else: return 0
|
||||
if f-i == 0:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
except:
|
||||
return 0
|
||||
|
||||
iforms = [1, 3, -11, -12, -21, -22]
|
||||
|
||||
|
||||
# There is no magic number to identify Spider files, so just check a
|
||||
# series of header locations to see if they have reasonable values.
|
||||
# Returns no.of bytes in the header, if it is a valid Spider header,
|
||||
|
@ -57,28 +63,30 @@ def isSpiderHeader(t):
|
|||
h = (99,) + t # add 1 value so can use spider header index start=1
|
||||
# header values 1,2,5,12,13,22,23 should be integers
|
||||
for i in [1, 2, 5, 12, 13, 22, 23]:
|
||||
if not isInt(h[i]): return 0
|
||||
if not isInt(h[i]):
|
||||
return 0
|
||||
# check iform
|
||||
iform = int(h[5])
|
||||
if not iform in iforms: return 0
|
||||
if iform not in iforms:
|
||||
return 0
|
||||
# check other header values
|
||||
labrec = int(h[13]) # no. records in file header
|
||||
labbyt = int(h[22]) # total no. of bytes in header
|
||||
lenbyt = int(h[23]) # record length in bytes
|
||||
# print "labrec = %d, labbyt = %d, lenbyt = %d" % (labrec,labbyt,lenbyt)
|
||||
if labbyt != (labrec * lenbyt): return 0
|
||||
if labbyt != (labrec * lenbyt):
|
||||
return 0
|
||||
# looks like a valid header
|
||||
return labbyt
|
||||
|
||||
|
||||
def isSpiderImage(filename):
|
||||
fp = open(filename, 'rb')
|
||||
f = fp.read(92) # read 23 * 4 bytes
|
||||
fp.close()
|
||||
bigendian = 1
|
||||
t = struct.unpack('>23f', f) # try big-endian first
|
||||
hdrlen = isSpiderHeader(t)
|
||||
if hdrlen == 0:
|
||||
bigendian = 0
|
||||
t = struct.unpack('<23f', f) # little-endian
|
||||
hdrlen = isSpiderHeader(t)
|
||||
return hdrlen
|
||||
|
@ -141,7 +149,8 @@ class SpiderImageFile(ImageFile.ImageFile):
|
|||
self.rawmode = "F;32F"
|
||||
self.mode = "F"
|
||||
|
||||
self.tile = [("raw", (0, 0) + self.size, offset,
|
||||
self.tile = [
|
||||
("raw", (0, 0) + self.size, offset,
|
||||
(self.rawmode, 0, 1))]
|
||||
self.__fp = self.fp # FIXME: hack
|
||||
|
||||
|
@ -176,6 +185,7 @@ class SpiderImageFile(ImageFile.ImageFile):
|
|||
from PIL import ImageTk
|
||||
return ImageTk.PhotoImage(self.convert2byte(), palette=256)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Image series
|
||||
|
||||
|
@ -200,6 +210,7 @@ def loadImageSeries(filelist=None):
|
|||
imglist.append(im)
|
||||
return imglist
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# For saving images in Spider format
|
||||
|
||||
|
@ -207,10 +218,11 @@ def makeSpiderHeader(im):
|
|||
nsam, nrow = im.size
|
||||
lenbyt = nsam * 4 # There are labrec records in the header
|
||||
labrec = 1024 / lenbyt
|
||||
if 1024%lenbyt != 0: labrec += 1
|
||||
if 1024 % lenbyt != 0:
|
||||
labrec += 1
|
||||
labbyt = labrec * lenbyt
|
||||
hdr = []
|
||||
nvalues = labbyt / 4
|
||||
nvalues = int(labbyt / 4)
|
||||
for i in range(nvalues):
|
||||
hdr.append(0.0)
|
||||
|
||||
|
@ -235,6 +247,7 @@ def makeSpiderHeader(im):
|
|||
hdrstr.append(struct.pack('f', v))
|
||||
return hdrstr
|
||||
|
||||
|
||||
def _save(im, fp, filename):
|
||||
if im.mode[0] != "F":
|
||||
im = im.convert('F')
|
||||
|
@ -255,6 +268,7 @@ def _save(im, fp, filename):
|
|||
|
||||
fp.close()
|
||||
|
||||
|
||||
def _save_spider(im, fp, filename):
|
||||
# get the filename extension and register it with Image
|
||||
fn, ext = os.path.splitext(filename)
|
||||
|
@ -292,5 +306,7 @@ if __name__ == "__main__":
|
|||
if outfile != "":
|
||||
# perform some image operation
|
||||
im = im.transpose(Image.FLIP_LEFT_RIGHT)
|
||||
print("saving a flipped version of %s as %s " % (os.path.basename(filename), outfile))
|
||||
print(
|
||||
"saving a flipped version of %s as %s " %
|
||||
(os.path.basename(filename), outfile))
|
||||
im.save(outfile, "SPIDER")
|
||||
|
|
|
@ -859,7 +859,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
# libtiff handles the fillmode for us, so 1;IR should
|
||||
# actually be 1;I. Including the R double reverses the
|
||||
# bits, so stripes of the image are reversed. See
|
||||
# https://github.com/python-imaging/Pillow/issues/279
|
||||
# https://github.com/python-pillow/Pillow/issues/279
|
||||
if fillorder == 2:
|
||||
key = (
|
||||
self.tag.prefix, photo, format, 1,
|
||||
|
@ -984,11 +984,7 @@ def _save(im, fp, filename):
|
|||
|
||||
compression = im.encoderinfo.get('compression',im.info.get('compression','raw'))
|
||||
|
||||
libtiff = WRITE_LIBTIFF or compression in ["tiff_ccitt", "group3", "group4",
|
||||
"tiff_jpeg", "tiff_adobe_deflate",
|
||||
"tiff_thunderscan", "tiff_deflate",
|
||||
"tiff_sgilog", "tiff_sgilog24",
|
||||
"tiff_raw_16"]
|
||||
libtiff = WRITE_LIBTIFF or compression != 'raw'
|
||||
|
||||
# required for color libtiff images
|
||||
ifd[PLANAR_CONFIGURATION] = getattr(im, '_planar_configuration', 1)
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
#
|
||||
|
||||
# NOTE: This format cannot be automatically recognized, so the reader
|
||||
# is not registered for use with Image.open(). To open a WEL file, use
|
||||
# is not registered for use with Image.open(). To open a WAL file, use
|
||||
# the WalImageFile.open() function instead.
|
||||
|
||||
# This reader is based on the specification available from:
|
||||
# http://www.flipcode.com/tutorials/tut_q2levels.shtml
|
||||
# http://www.flipcode.com/archives/Quake_2_BSP_File_Format.shtml
|
||||
# and has been tested with a few sample files found using google.
|
||||
|
||||
from __future__ import print_function
|
||||
|
|
|
@ -5,8 +5,8 @@ Pillow
|
|||
|
||||
Pillow is the "friendly" PIL fork by Alex Clark and Contributors. PIL is the Python Imaging Library by Fredrik Lundh and Contributors.
|
||||
|
||||
.. image:: https://travis-ci.org/python-imaging/Pillow.svg?branch=master
|
||||
:target: https://travis-ci.org/python-imaging/Pillow
|
||||
.. image:: https://travis-ci.org/python-pillow/Pillow.svg?branch=master
|
||||
:target: https://travis-ci.org/python-pillow/Pillow
|
||||
:alt: Travis CI build status
|
||||
|
||||
.. image:: https://pypip.in/v/Pillow/badge.png
|
||||
|
@ -17,7 +17,7 @@ Pillow is the "friendly" PIL fork by Alex Clark and Contributors. PIL is the Pyt
|
|||
:target: https://pypi.python.org/pypi/Pillow/
|
||||
:alt: Number of PyPI downloads
|
||||
|
||||
.. image:: https://coveralls.io/repos/python-imaging/Pillow/badge.png?branch=master
|
||||
:target: https://coveralls.io/r/python-imaging/Pillow?branch=master
|
||||
.. image:: https://coveralls.io/repos/python-pillow/Pillow/badge.png?branch=master
|
||||
:target: https://coveralls.io/r/python-pillow/Pillow?branch=master
|
||||
|
||||
The documentation is hosted at http://pillow.readthedocs.org/. It contains installation instructions, tutorials, reference, compatibility details, and more.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
Python SANE module V1.1 (30 Sep. 2004)
|
||||
================================================================================
|
||||
|
||||
The SANE module provides an interface to the SANE scanner and frame
|
||||
grabber interface for Linux. This module was contributed by Andrew
|
||||
|
@ -9,11 +9,11 @@ word 'SANE' or 'sane' in the subject of your mail, otherwise it might
|
|||
be classified as spam in the future.
|
||||
|
||||
|
||||
To build this module, type (in the Sane directory):
|
||||
To build this module, type (in the Sane directory)::
|
||||
|
||||
python setup.py build
|
||||
|
||||
In order to install the module type:
|
||||
In order to install the module type::
|
||||
|
||||
python setup.py install
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
-------
|
||||
Scripts
|
||||
-------
|
||||
=======
|
||||
|
||||
This directory contains a number of more or less trivial utilities
|
||||
and demo programs.
|
||||
|
@ -9,50 +8,50 @@ Comments and contributions are welcome.
|
|||
|
||||
</F>
|
||||
|
||||
--------------------------------------------------------------------
|
||||
pildriver.py (by Eric S. Raymond)
|
||||
--------------------------------------------------------------------
|
||||
|
||||
A class implementing an image-processing calculator for scripts.
|
||||
Parses lists of commnds (or, called interactively, command-line
|
||||
arguments) into image loads, transformations, and saves.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
viewer.py
|
||||
--------------------------------------------------------------------
|
||||
|
||||
A simple image viewer. Can display all file formats handled by
|
||||
PIL. Transparent images are properly handled.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
thresholder.py
|
||||
--------------------------------------------------------------------
|
||||
|
||||
A simple utility that demonstrates how a transparent 1-bit overlay
|
||||
can be used to show the current thresholding of an 8-bit image.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
enhancer.py
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Illustrates the ImageEnhance module. Drag the sliders to modify the
|
||||
images. This might be very slow on some platforms, depending on the
|
||||
Tk version.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
painter.py
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Illustrates how a painting program could be based on PIL and Tk.
|
||||
Press the left mouse button and drag over the image to remove the
|
||||
colour. Some clever tricks have been used to get decent performance
|
||||
when updating the screen; see the sources for details.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
player.py
|
||||
--------------------------------------------------------------------
|
||||
|
||||
A simple image sequence player. You can use either a sequence format
|
||||
like FLI/FLC, GIF, or ARG, or give a number of images which are
|
||||
interpreted as frames in a sequence. All frames must have the same
|
||||
size.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
gifmaker.py
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Convert a sequence file to a GIF animation.
|
||||
|
||||
|
@ -60,20 +59,20 @@ Note that the GIF encoder provided with this release of PIL writes
|
|||
uncompressed GIF files only, so the resulting animations are rather
|
||||
large compared with these created by other tools.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
explode.py
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Split a sequence file into individual frames.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
image2py.py
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Convert an image to a Python module containing an IMAGE variable.
|
||||
Note that the module using the module must include JPEG and ZIP
|
||||
decoders, unless the -u option is used.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
olesummary.py
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Uses the OleFileIO module to dump the summary information from an OLE
|
||||
structured storage file. This works with most OLE files, including
|
341
Tests/helper.py
Normal file
|
@ -0,0 +1,341 @@
|
|||
"""
|
||||
Helper functions.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
|
||||
if sys.version_info[:2] <= (2, 6):
|
||||
import unittest2 as unittest
|
||||
else:
|
||||
import unittest
|
||||
|
||||
|
||||
def tearDownModule():
|
||||
import glob
|
||||
import os
|
||||
import tempfile
|
||||
temp_root = os.path.join(tempfile.gettempdir(), 'pillow-tests')
|
||||
tempfiles = glob.glob(os.path.join(temp_root, "temp_*"))
|
||||
if tempfiles:
|
||||
print("===", "remaining temporary files")
|
||||
for file in tempfiles:
|
||||
print(file)
|
||||
print("-"*68)
|
||||
|
||||
|
||||
class PillowTestCase(unittest.TestCase):
|
||||
|
||||
currentResult = None # holds last result object passed to run method
|
||||
_tempfiles = []
|
||||
|
||||
def run(self, result=None):
|
||||
self.addCleanup(self.delete_tempfiles)
|
||||
self.currentResult = result # remember result for use later
|
||||
unittest.TestCase.run(self, result) # call superclass run method
|
||||
|
||||
def delete_tempfiles(self):
|
||||
try:
|
||||
ok = self.currentResult.wasSuccessful()
|
||||
except AttributeError: # for nosetests
|
||||
proxy = self.currentResult
|
||||
ok = (len(proxy.errors) + len(proxy.failures) == 0)
|
||||
|
||||
if ok:
|
||||
# only clean out tempfiles if test passed
|
||||
import os
|
||||
import os.path
|
||||
import tempfile
|
||||
for file in self._tempfiles:
|
||||
try:
|
||||
os.remove(file)
|
||||
except OSError:
|
||||
pass # report?
|
||||
temp_root = os.path.join(tempfile.gettempdir(), 'pillow-tests')
|
||||
try:
|
||||
os.rmdir(temp_root)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def assert_almost_equal(self, a, b, msg=None, eps=1e-6):
|
||||
self.assertLess(
|
||||
abs(a-b), eps,
|
||||
msg or "got %r, expected %r" % (a, b))
|
||||
|
||||
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)))
|
||||
self.assertTrue(
|
||||
all([x == y for x, y in zip(a, b)]),
|
||||
msg or "got %s, expected %s" % (a, b))
|
||||
except:
|
||||
self.assertEqual(a, b, msg)
|
||||
|
||||
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))
|
||||
|
||||
if size is not None:
|
||||
self.assertEqual(
|
||||
im.size, size,
|
||||
msg or "got size %r, expected %r" % (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))
|
||||
self.assertEqual(
|
||||
a.size, b.size,
|
||||
msg or "got size %r, expected %r" % (a.size, b.size))
|
||||
self.assertEqual(
|
||||
a.tobytes(), b.tobytes(),
|
||||
msg or "got different content")
|
||||
|
||||
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))
|
||||
self.assertEqual(
|
||||
a.size, b.size,
|
||||
msg or "got size %r, expected %r" % (a.size, b.size))
|
||||
|
||||
diff = 0
|
||||
try:
|
||||
ord(b'0')
|
||||
for abyte, bbyte in zip(a.tobytes(), b.tobytes()):
|
||||
diff += abs(ord(abyte)-ord(bbyte))
|
||||
except:
|
||||
for abyte, bbyte in zip(a.tobytes(), b.tobytes()):
|
||||
diff += abs(abyte-bbyte)
|
||||
ave_diff = float(diff)/(a.size[0]*a.size[1])
|
||||
self.assertGreaterEqual(
|
||||
epsilon, ave_diff,
|
||||
msg or "average pixel value difference %.4f > epsilon %.4f" % (
|
||||
ave_diff, epsilon))
|
||||
|
||||
def assert_warning(self, warn_class, func):
|
||||
import warnings
|
||||
|
||||
result = None
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
# Cause all warnings to always be triggered.
|
||||
warnings.simplefilter("always")
|
||||
|
||||
# Hopefully trigger a warning.
|
||||
result = func()
|
||||
|
||||
# Verify some things.
|
||||
self.assertGreaterEqual(len(w), 1)
|
||||
found = False
|
||||
for v in w:
|
||||
if issubclass(v.category, warn_class):
|
||||
found = True
|
||||
break
|
||||
self.assertTrue(found)
|
||||
return result
|
||||
|
||||
def tempfile(self, template, *extra):
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
import tempfile
|
||||
files = []
|
||||
root = os.path.join(tempfile.gettempdir(), 'pillow-tests')
|
||||
try:
|
||||
os.mkdir(root)
|
||||
except OSError:
|
||||
pass
|
||||
for temp in (template,) + extra:
|
||||
assert temp[:5] in ("temp.", "temp_")
|
||||
name = os.path.basename(sys.argv[0])
|
||||
name = temp[:4] + os.path.splitext(name)[0][4:]
|
||||
name = name + "_%d" % len(self._tempfiles) + temp[4:]
|
||||
name = os.path.join(root, name)
|
||||
files.append(name)
|
||||
self._tempfiles.extend(files)
|
||||
return files[0]
|
||||
|
||||
|
||||
# # require that deprecation warnings are triggered
|
||||
# import warnings
|
||||
# warnings.simplefilter('default')
|
||||
# # temporarily turn off resource warnings that warn about unclosed
|
||||
# # files in the test scripts.
|
||||
# try:
|
||||
# warnings.filterwarnings("ignore", category=ResourceWarning)
|
||||
# except NameError:
|
||||
# # we expect a NameError on py2.x, since it doesn't have ResourceWarnings.
|
||||
# pass
|
||||
|
||||
import sys
|
||||
py3 = (sys.version_info >= (3, 0))
|
||||
|
||||
# # some test helpers
|
||||
#
|
||||
# _target = None
|
||||
# _tempfiles = []
|
||||
# _logfile = None
|
||||
#
|
||||
#
|
||||
# def success():
|
||||
# import sys
|
||||
# success.count += 1
|
||||
# if _logfile:
|
||||
# print(sys.argv[0], success.count, failure.count, file=_logfile)
|
||||
# return True
|
||||
#
|
||||
#
|
||||
# def failure(msg=None, frame=None):
|
||||
# import sys
|
||||
# import linecache
|
||||
# failure.count += 1
|
||||
# if _target:
|
||||
# if frame is None:
|
||||
# frame = sys._getframe()
|
||||
# while frame.f_globals.get("__name__") != _target.__name__:
|
||||
# frame = frame.f_back
|
||||
# location = (frame.f_code.co_filename, frame.f_lineno)
|
||||
# prefix = "%s:%d: " % location
|
||||
# line = linecache.getline(*location)
|
||||
# print(prefix + line.strip() + " failed:")
|
||||
# if msg:
|
||||
# print("- " + msg)
|
||||
# if _logfile:
|
||||
# print(sys.argv[0], success.count, failure.count, file=_logfile)
|
||||
# return False
|
||||
#
|
||||
# success.count = failure.count = 0
|
||||
#
|
||||
|
||||
|
||||
# helpers
|
||||
|
||||
def fromstring(data):
|
||||
from io import BytesIO
|
||||
from PIL import Image
|
||||
return Image.open(BytesIO(data))
|
||||
|
||||
|
||||
def tostring(im, format, **options):
|
||||
from io import BytesIO
|
||||
out = BytesIO()
|
||||
im.save(out, format, **options)
|
||||
return out.getvalue()
|
||||
|
||||
|
||||
def lena(mode="RGB", cache={}):
|
||||
from PIL import Image
|
||||
im = None
|
||||
# im = cache.get(mode)
|
||||
if im is None:
|
||||
if mode == "RGB":
|
||||
im = Image.open("Images/lena.ppm")
|
||||
elif mode == "F":
|
||||
im = lena("L").convert(mode)
|
||||
elif mode[:4] == "I;16":
|
||||
im = lena("I").convert(mode)
|
||||
else:
|
||||
im = lena("RGB").convert(mode)
|
||||
# cache[mode] = im
|
||||
return im
|
||||
|
||||
|
||||
# def assert_image_completely_equal(a, b, msg=None):
|
||||
# if a != b:
|
||||
# failure(msg or "images different")
|
||||
# else:
|
||||
# success()
|
||||
#
|
||||
#
|
||||
# # test runner
|
||||
#
|
||||
# def run():
|
||||
# global _target, _tests, run
|
||||
# import sys
|
||||
# import traceback
|
||||
# _target = sys.modules["__main__"]
|
||||
# run = None # no need to run twice
|
||||
# tests = []
|
||||
# for name, value in list(vars(_target).items()):
|
||||
# if name[:5] == "test_" and type(value) is type(success):
|
||||
# tests.append((value.__code__.co_firstlineno, name, value))
|
||||
# tests.sort() # sort by line
|
||||
# for lineno, name, func in tests:
|
||||
# try:
|
||||
# _tests = []
|
||||
# func()
|
||||
# for func, args in _tests:
|
||||
# func(*args)
|
||||
# except:
|
||||
# t, v, tb = sys.exc_info()
|
||||
# tb = tb.tb_next
|
||||
# if tb:
|
||||
# failure(frame=tb.tb_frame)
|
||||
# traceback.print_exception(t, v, tb)
|
||||
# else:
|
||||
# print("%s:%d: cannot call test function: %s" % (
|
||||
# sys.argv[0], lineno, v))
|
||||
# failure.count += 1
|
||||
#
|
||||
#
|
||||
# def yield_test(function, *args):
|
||||
# # collect delayed/generated tests
|
||||
# _tests.append((function, args))
|
||||
#
|
||||
#
|
||||
# def skip(msg=None):
|
||||
# import os
|
||||
# print("skip")
|
||||
# os._exit(0) # don't run exit handlers
|
||||
#
|
||||
#
|
||||
# def ignore(pattern):
|
||||
# """Tells the driver to ignore messages matching the pattern, for the
|
||||
# duration of the current test."""
|
||||
# print('ignore: %s' % pattern)
|
||||
#
|
||||
#
|
||||
# def _setup():
|
||||
# global _logfile
|
||||
#
|
||||
# import sys
|
||||
# if "--coverage" in sys.argv:
|
||||
# # Temporary: ignore PendingDeprecationWarning from Coverage (Py3.4)
|
||||
# with warnings.catch_warnings():
|
||||
# warnings.simplefilter("ignore")
|
||||
# import coverage
|
||||
# cov = coverage.coverage(auto_data=True, include="PIL/*")
|
||||
# cov.start()
|
||||
#
|
||||
# def report():
|
||||
# if run:
|
||||
# run()
|
||||
# if success.count and not failure.count:
|
||||
# print("ok")
|
||||
# # only clean out tempfiles if test passed
|
||||
# import os
|
||||
# import os.path
|
||||
# import tempfile
|
||||
# for file in _tempfiles:
|
||||
# try:
|
||||
# os.remove(file)
|
||||
# except OSError:
|
||||
# pass # report?
|
||||
# temp_root = os.path.join(tempfile.gettempdir(), 'pillow-tests')
|
||||
# try:
|
||||
# os.rmdir(temp_root)
|
||||
# except OSError:
|
||||
# pass
|
||||
#
|
||||
# import atexit
|
||||
# atexit.register(report)
|
||||
#
|
||||
# if "--log" in sys.argv:
|
||||
# _logfile = open("test.log", "a")
|
||||
#
|
||||
#
|
||||
# _setup()
|
BIN
Tests/images/binary_preview_map.eps
Executable file
BIN
Tests/images/imagedraw_arc.png
Normal file
After Width: | Height: | Size: 284 B |
BIN
Tests/images/imagedraw_bitmap.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
Tests/images/imagedraw_chord.png
Normal file
After Width: | Height: | Size: 326 B |
BIN
Tests/images/imagedraw_ellipse.png
Normal file
After Width: | Height: | Size: 491 B |
BIN
Tests/images/imagedraw_floodfill.png
Normal file
After Width: | Height: | Size: 232 B |
BIN
Tests/images/imagedraw_floodfill2.png
Normal file
After Width: | Height: | Size: 212 B |
BIN
Tests/images/imagedraw_line.png
Normal file
After Width: | Height: | Size: 286 B |
BIN
Tests/images/imagedraw_pieslice.png
Normal file
After Width: | Height: | Size: 405 B |
BIN
Tests/images/imagedraw_point.png
Normal file
After Width: | Height: | Size: 124 B |
BIN
Tests/images/imagedraw_polygon.png
Normal file
After Width: | Height: | Size: 292 B |
BIN
Tests/images/imagedraw_rectangle.png
Normal file
After Width: | Height: | Size: 228 B |
BIN
Tests/images/junk_jpeg_header.jpg
Normal file
After Width: | Height: | Size: 105 KiB |
BIN
Tests/images/lena.spider
Normal file
|
@ -1,18 +1,22 @@
|
|||
from __future__ import print_function
|
||||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
import PIL
|
||||
import PIL.Image
|
||||
|
||||
|
||||
class TestSanity(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
# Make sure we have the binary extension
|
||||
im = PIL.Image.core.new("L", (100, 100))
|
||||
|
||||
assert PIL.Image.VERSION[:3] == '1.1'
|
||||
self.assertEqual(PIL.Image.VERSION[:3], '1.1')
|
||||
|
||||
# Create an image and do stuff with it.
|
||||
im = PIL.Image.new("1", (100, 100))
|
||||
assert (im.mode, im.size) == ('1', (100, 100))
|
||||
assert len(im.tobytes()) == 1300
|
||||
self.assertEqual((im.mode, im.size), ('1', (100, 100)))
|
||||
self.assertEqual(len(im.tobytes()), 1300)
|
||||
|
||||
# Create images in all remaining major modes.
|
||||
im = PIL.Image.new("L", (100, 100))
|
||||
|
@ -21,4 +25,8 @@ im = PIL.Image.new("RGB", (100, 100))
|
|||
im = PIL.Image.new("I", (100, 100))
|
||||
im = PIL.Image.new("F", (100, 100))
|
||||
|
||||
print("ok")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import PIL
|
||||
import PIL.Image
|
||||
|
||||
import glob, os
|
||||
|
||||
for file in glob.glob("../pil-archive/*"):
|
||||
f, e = os.path.splitext(file)
|
||||
if e in [".txt", ".ttf", ".otf", ".zip"]:
|
||||
continue
|
||||
try:
|
||||
im = PIL.Image.open(file)
|
||||
im.load()
|
||||
except IOError as v:
|
||||
print("-", "failed to open", file, "-", v)
|
||||
else:
|
||||
print("+", file, im.mode, im.size, im.format)
|
||||
if e == ".exif":
|
||||
try:
|
||||
info = im._getexif()
|
||||
except KeyError as v:
|
||||
print("-", "failed to get exif info from", file, "-", v)
|
||||
|
||||
print("ok")
|
|
@ -1,4 +1,4 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
import os
|
||||
|
@ -6,32 +6,35 @@ import os
|
|||
base = os.path.join('Tests', 'images', 'bmp')
|
||||
|
||||
|
||||
def get_files(d, ext='.bmp'):
|
||||
class TestBmpReference(PillowTestCase):
|
||||
|
||||
def get_files(self, d, ext='.bmp'):
|
||||
return [os.path.join(base, d, f) for f
|
||||
in os.listdir(os.path.join(base, d)) if ext in f]
|
||||
|
||||
def test_bad():
|
||||
""" These shouldn't crash/dos, but they shouldn't return anything either """
|
||||
for f in get_files('b'):
|
||||
def test_bad(self):
|
||||
""" These shouldn't crash/dos, but they shouldn't return anything
|
||||
either """
|
||||
for f in self.get_files('b'):
|
||||
try:
|
||||
im = Image.open(f)
|
||||
im.load()
|
||||
except Exception as msg:
|
||||
except Exception: # as msg:
|
||||
pass
|
||||
# print ("Bad Image %s: %s" %(f,msg))
|
||||
|
||||
def test_questionable():
|
||||
""" These shouldn't crash/dos, but its not well defined that these are in spec """
|
||||
for f in get_files('q'):
|
||||
def test_questionable(self):
|
||||
""" These shouldn't crash/dos, but its not well defined that these
|
||||
are in spec """
|
||||
for f in self.get_files('q'):
|
||||
try:
|
||||
im = Image.open(f)
|
||||
im.load()
|
||||
except Exception as msg:
|
||||
except Exception: # as msg:
|
||||
pass
|
||||
# print ("Bad Image %s: %s" %(f,msg))
|
||||
|
||||
|
||||
def test_good():
|
||||
def test_good(self):
|
||||
""" These should all work. There's a set of target files in the
|
||||
html directory that we can compare against. """
|
||||
|
||||
|
@ -61,7 +64,7 @@ def test_good():
|
|||
(name, ext) = os.path.splitext(name)
|
||||
return os.path.join(base, 'html', "%s.png" % name)
|
||||
|
||||
for f in get_files('g'):
|
||||
for f in self.get_files('g'):
|
||||
try:
|
||||
im = Image.open(f)
|
||||
im.load()
|
||||
|
@ -73,8 +76,7 @@ def test_good():
|
|||
# be differently ordered for an equivalent image.
|
||||
im = im.convert('RGBA')
|
||||
compare = im.convert('RGBA')
|
||||
assert_image_similar(im, compare,5)
|
||||
|
||||
self.assert_image_similar(im, compare, 5)
|
||||
|
||||
except Exception as msg:
|
||||
# there are three here that are unsupported:
|
||||
|
@ -82,5 +84,11 @@ def test_good():
|
|||
os.path.join(base, 'g', 'pal8rle.bmp'),
|
||||
os.path.join(base, 'g', 'pal4rle.bmp'))
|
||||
if f not in unsupported:
|
||||
assert_true(False, "Unsupported Image %s: %s" %(f,msg))
|
||||
self.assertTrue(
|
||||
False, "Unsupported Image %s: %s" % (f, msg))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,69 +1,99 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
try:
|
||||
import cffi
|
||||
from PIL import PyAccess
|
||||
except:
|
||||
skip()
|
||||
# Skip in setUp()
|
||||
pass
|
||||
|
||||
from PIL import Image, PyAccess
|
||||
|
||||
import test_image_putpixel as put
|
||||
import test_image_getpixel as get
|
||||
from PIL import Image
|
||||
|
||||
from test_image_putpixel import TestImagePutPixel
|
||||
from test_image_getpixel import TestImageGetPixel
|
||||
|
||||
Image.USE_CFFI_ACCESS = True
|
||||
|
||||
def test_put():
|
||||
put.test_sanity()
|
||||
|
||||
def test_get():
|
||||
get.test_basic()
|
||||
get.test_signedness()
|
||||
class TestCffiPutPixel(TestImagePutPixel):
|
||||
|
||||
def _test_get_access(im):
|
||||
def setUp(self):
|
||||
try:
|
||||
import cffi
|
||||
except:
|
||||
self.skipTest("No cffi")
|
||||
|
||||
def test_put(self):
|
||||
self.test_sanity()
|
||||
|
||||
|
||||
class TestCffiGetPixel(TestImageGetPixel):
|
||||
|
||||
def setUp(self):
|
||||
try:
|
||||
import cffi
|
||||
except:
|
||||
self.skipTest("No cffi")
|
||||
|
||||
def test_get(self):
|
||||
self.test_basic()
|
||||
self.test_signedness()
|
||||
|
||||
|
||||
class TestCffi(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
try:
|
||||
import cffi
|
||||
except:
|
||||
self.skipTest("No cffi")
|
||||
|
||||
def _test_get_access(self, im):
|
||||
""" Do we get the same thing as the old pixel access """
|
||||
|
||||
""" Using private interfaces, forcing a capi access and a pyaccess for the same image """
|
||||
""" Using private interfaces, forcing a capi access and
|
||||
a pyaccess for the same image """
|
||||
caccess = im.im.pixel_access(False)
|
||||
access = PyAccess.new(im, False)
|
||||
|
||||
w, h = im.size
|
||||
for x in range(0, w, 10):
|
||||
for y in range(0, h, 10):
|
||||
assert_equal(access[(x,y)], caccess[(x,y)])
|
||||
self.assertEqual(access[(x, y)], caccess[(x, y)])
|
||||
|
||||
def test_get_vs_c():
|
||||
_test_get_access(lena('RGB'))
|
||||
_test_get_access(lena('RGBA'))
|
||||
_test_get_access(lena('L'))
|
||||
_test_get_access(lena('LA'))
|
||||
_test_get_access(lena('1'))
|
||||
_test_get_access(lena('P'))
|
||||
#_test_get_access(lena('PA')) # PA -- how do I make a PA image???
|
||||
_test_get_access(lena('F'))
|
||||
def test_get_vs_c(self):
|
||||
rgb = lena('RGB')
|
||||
rgb.load()
|
||||
self._test_get_access(rgb)
|
||||
self._test_get_access(lena('RGBA'))
|
||||
self._test_get_access(lena('L'))
|
||||
self._test_get_access(lena('LA'))
|
||||
self._test_get_access(lena('1'))
|
||||
self._test_get_access(lena('P'))
|
||||
# self._test_get_access(lena('PA')) # PA -- how do I make a PA image?
|
||||
self._test_get_access(lena('F'))
|
||||
|
||||
im = Image.new('I;16', (10, 10), 40000)
|
||||
_test_get_access(im)
|
||||
self._test_get_access(im)
|
||||
im = Image.new('I;16L', (10, 10), 40000)
|
||||
_test_get_access(im)
|
||||
self._test_get_access(im)
|
||||
im = Image.new('I;16B', (10, 10), 40000)
|
||||
_test_get_access(im)
|
||||
self._test_get_access(im)
|
||||
|
||||
im = Image.new('I', (10, 10), 40000)
|
||||
_test_get_access(im)
|
||||
self._test_get_access(im)
|
||||
# These don't actually appear to be modes that I can actually make,
|
||||
# as unpack sets them directly into the I mode.
|
||||
# im = Image.new('I;32L', (10, 10), -2**10)
|
||||
#_test_get_access(im)
|
||||
# self._test_get_access(im)
|
||||
# im = Image.new('I;32B', (10, 10), 2**10)
|
||||
#_test_get_access(im)
|
||||
# self._test_get_access(im)
|
||||
|
||||
|
||||
|
||||
def _test_set_access(im, color):
|
||||
def _test_set_access(self, im, color):
|
||||
""" Are we writing the correct bits into the image? """
|
||||
|
||||
""" Using private interfaces, forcing a capi access and a pyaccess for the same image """
|
||||
""" Using private interfaces, forcing a capi access and
|
||||
a pyaccess for the same image """
|
||||
caccess = im.im.pixel_access(False)
|
||||
access = PyAccess.new(im, False)
|
||||
|
||||
|
@ -71,29 +101,36 @@ def _test_set_access(im, color):
|
|||
for x in range(0, w, 10):
|
||||
for y in range(0, h, 10):
|
||||
access[(x, y)] = color
|
||||
assert_equal(color, caccess[(x,y)])
|
||||
self.assertEqual(color, caccess[(x, y)])
|
||||
|
||||
def test_set_vs_c():
|
||||
_test_set_access(lena('RGB'), (255, 128,0) )
|
||||
_test_set_access(lena('RGBA'), (255, 192, 128, 0))
|
||||
_test_set_access(lena('L'), 128)
|
||||
_test_set_access(lena('LA'), (128,128))
|
||||
_test_set_access(lena('1'), 255)
|
||||
_test_set_access(lena('P') , 128)
|
||||
##_test_set_access(i, (128,128)) #PA -- undone how to make
|
||||
_test_set_access(lena('F'), 1024.0)
|
||||
def test_set_vs_c(self):
|
||||
rgb = lena('RGB')
|
||||
rgb.load()
|
||||
self._test_set_access(rgb, (255, 128, 0))
|
||||
self._test_set_access(lena('RGBA'), (255, 192, 128, 0))
|
||||
self._test_set_access(lena('L'), 128)
|
||||
self._test_set_access(lena('LA'), (128, 128))
|
||||
self._test_set_access(lena('1'), 255)
|
||||
self._test_set_access(lena('P'), 128)
|
||||
# self._test_set_access(i, (128, 128)) #PA -- undone how to make
|
||||
self._test_set_access(lena('F'), 1024.0)
|
||||
|
||||
im = Image.new('I;16', (10, 10), 40000)
|
||||
_test_set_access(im, 45000)
|
||||
self._test_set_access(im, 45000)
|
||||
im = Image.new('I;16L', (10, 10), 40000)
|
||||
_test_set_access(im, 45000)
|
||||
self._test_set_access(im, 45000)
|
||||
im = Image.new('I;16B', (10, 10), 40000)
|
||||
_test_set_access(im, 45000)
|
||||
|
||||
self._test_set_access(im, 45000)
|
||||
|
||||
im = Image.new('I', (10, 10), 40000)
|
||||
_test_set_access(im, 45000)
|
||||
self._test_set_access(im, 45000)
|
||||
# im = Image.new('I;32L', (10, 10), -(2**10))
|
||||
# _test_set_access(im, -(2**13)+1)
|
||||
# self._test_set_access(im, -(2**13)+1)
|
||||
# im = Image.new('I;32B', (10, 10), 2**10)
|
||||
#_test_set_access(im, 2**13-1)
|
||||
# self._test_set_access(im, 2**13-1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,30 +1,31 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
import io
|
||||
|
||||
def roundtrip(im):
|
||||
outfile = tempfile("temp.bmp")
|
||||
|
||||
class TestFileBmp(PillowTestCase):
|
||||
|
||||
def roundtrip(self, im):
|
||||
outfile = self.tempfile("temp.bmp")
|
||||
|
||||
im.save(outfile, 'BMP')
|
||||
|
||||
reloaded = Image.open(outfile)
|
||||
reloaded.load()
|
||||
assert_equal(im.mode, reloaded.mode)
|
||||
assert_equal(im.size, reloaded.size)
|
||||
assert_equal(reloaded.format, "BMP")
|
||||
self.assertEqual(im.mode, reloaded.mode)
|
||||
self.assertEqual(im.size, reloaded.size)
|
||||
self.assertEqual(reloaded.format, "BMP")
|
||||
|
||||
def test_sanity(self):
|
||||
self.roundtrip(lena())
|
||||
|
||||
def test_sanity():
|
||||
roundtrip(lena())
|
||||
self.roundtrip(lena("1"))
|
||||
self.roundtrip(lena("L"))
|
||||
self.roundtrip(lena("P"))
|
||||
self.roundtrip(lena("RGB"))
|
||||
|
||||
roundtrip(lena("1"))
|
||||
roundtrip(lena("L"))
|
||||
roundtrip(lena("P"))
|
||||
roundtrip(lena("RGB"))
|
||||
|
||||
|
||||
def test_save_to_bytes():
|
||||
def test_save_to_bytes(self):
|
||||
output = io.BytesIO()
|
||||
im = lena()
|
||||
im.save(output, "BMP")
|
||||
|
@ -32,7 +33,12 @@ def test_save_to_bytes():
|
|||
output.seek(0)
|
||||
reloaded = Image.open(output)
|
||||
|
||||
assert_equal(im.mode, reloaded.mode)
|
||||
assert_equal(im.size, reloaded.size)
|
||||
assert_equal(reloaded.format, "BMP")
|
||||
self.assertEqual(im.mode, reloaded.mode)
|
||||
self.assertEqual(im.size, reloaded.size)
|
||||
self.assertEqual(reloaded.format, "BMP")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image, EpsImagePlugin
|
||||
import sys
|
||||
import io
|
||||
|
||||
if not EpsImagePlugin.has_ghostscript():
|
||||
skip()
|
||||
|
||||
# Our two EPS test files (they are identical except for their bounding boxes)
|
||||
file1 = "Tests/images/zero_bb.eps"
|
||||
file2 = "Tests/images/non_zero_bb.eps"
|
||||
|
@ -18,81 +14,130 @@ file1_compare_scale2 = "Tests/images/zero_bb_scale2.png"
|
|||
file2_compare = "Tests/images/non_zero_bb.png"
|
||||
file2_compare_scale2 = "Tests/images/non_zero_bb_scale2.png"
|
||||
|
||||
def test_sanity():
|
||||
# EPS test files with binary preview
|
||||
file3 = "Tests/images/binary_preview_map.eps"
|
||||
|
||||
|
||||
class TestFileEps(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if not EpsImagePlugin.has_ghostscript():
|
||||
self.skipTest("Ghostscript not available")
|
||||
|
||||
def test_sanity(self):
|
||||
# Regular scale
|
||||
image1 = Image.open(file1)
|
||||
image1.load()
|
||||
assert_equal(image1.mode, "RGB")
|
||||
assert_equal(image1.size, (460, 352))
|
||||
assert_equal(image1.format, "EPS")
|
||||
self.assertEqual(image1.mode, "RGB")
|
||||
self.assertEqual(image1.size, (460, 352))
|
||||
self.assertEqual(image1.format, "EPS")
|
||||
|
||||
image2 = Image.open(file2)
|
||||
image2.load()
|
||||
assert_equal(image2.mode, "RGB")
|
||||
assert_equal(image2.size, (360, 252))
|
||||
assert_equal(image2.format, "EPS")
|
||||
self.assertEqual(image2.mode, "RGB")
|
||||
self.assertEqual(image2.size, (360, 252))
|
||||
self.assertEqual(image2.format, "EPS")
|
||||
|
||||
# Double scale
|
||||
image1_scale2 = Image.open(file1)
|
||||
image1_scale2.load(scale=2)
|
||||
assert_equal(image1_scale2.mode, "RGB")
|
||||
assert_equal(image1_scale2.size, (920, 704))
|
||||
assert_equal(image1_scale2.format, "EPS")
|
||||
self.assertEqual(image1_scale2.mode, "RGB")
|
||||
self.assertEqual(image1_scale2.size, (920, 704))
|
||||
self.assertEqual(image1_scale2.format, "EPS")
|
||||
|
||||
image2_scale2 = Image.open(file2)
|
||||
image2_scale2.load(scale=2)
|
||||
assert_equal(image2_scale2.mode, "RGB")
|
||||
assert_equal(image2_scale2.size, (720, 504))
|
||||
assert_equal(image2_scale2.format, "EPS")
|
||||
self.assertEqual(image2_scale2.mode, "RGB")
|
||||
self.assertEqual(image2_scale2.size, (720, 504))
|
||||
self.assertEqual(image2_scale2.format, "EPS")
|
||||
|
||||
def test_file_object():
|
||||
def test_file_object(self):
|
||||
# issue 479
|
||||
image1 = Image.open(file1)
|
||||
with open(tempfile('temp_file.eps'), 'wb') as fh:
|
||||
with open(self.tempfile('temp_file.eps'), 'wb') as fh:
|
||||
image1.save(fh, 'EPS')
|
||||
|
||||
def test_iobase_object():
|
||||
def test_iobase_object(self):
|
||||
# issue 479
|
||||
image1 = Image.open(file1)
|
||||
with io.open(tempfile('temp_iobase.eps'), 'wb') as fh:
|
||||
with io.open(self.tempfile('temp_iobase.eps'), 'wb') as fh:
|
||||
image1.save(fh, 'EPS')
|
||||
|
||||
def test_render_scale1():
|
||||
def test_render_scale1(self):
|
||||
# We need png support for these render test
|
||||
codecs = dir(Image.core)
|
||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
||||
skip("zip/deflate support not available")
|
||||
self.skipTest("zip/deflate support not available")
|
||||
|
||||
# Zero bounding box
|
||||
image1_scale1 = Image.open(file1)
|
||||
image1_scale1.load()
|
||||
image1_scale1_compare = Image.open(file1_compare).convert("RGB")
|
||||
image1_scale1_compare.load()
|
||||
assert_image_similar(image1_scale1, image1_scale1_compare, 5)
|
||||
self.assert_image_similar(image1_scale1, image1_scale1_compare, 5)
|
||||
|
||||
# Non-Zero bounding box
|
||||
image2_scale1 = Image.open(file2)
|
||||
image2_scale1.load()
|
||||
image2_scale1_compare = Image.open(file2_compare).convert("RGB")
|
||||
image2_scale1_compare.load()
|
||||
assert_image_similar(image2_scale1, image2_scale1_compare, 10)
|
||||
self.assert_image_similar(image2_scale1, image2_scale1_compare, 10)
|
||||
|
||||
def test_render_scale2():
|
||||
def test_render_scale2(self):
|
||||
# We need png support for these render test
|
||||
codecs = dir(Image.core)
|
||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
||||
skip("zip/deflate support not available")
|
||||
self.skipTest("zip/deflate support not available")
|
||||
|
||||
# Zero bounding box
|
||||
image1_scale2 = Image.open(file1)
|
||||
image1_scale2.load(scale=2)
|
||||
image1_scale2_compare = Image.open(file1_compare_scale2).convert("RGB")
|
||||
image1_scale2_compare.load()
|
||||
assert_image_similar(image1_scale2, image1_scale2_compare, 5)
|
||||
self.assert_image_similar(image1_scale2, image1_scale2_compare, 5)
|
||||
|
||||
# Non-Zero bounding box
|
||||
image2_scale2 = Image.open(file2)
|
||||
image2_scale2.load(scale=2)
|
||||
image2_scale2_compare = Image.open(file2_compare_scale2).convert("RGB")
|
||||
image2_scale2_compare.load()
|
||||
assert_image_similar(image2_scale2, image2_scale2_compare, 10)
|
||||
self.assert_image_similar(image2_scale2, image2_scale2_compare, 10)
|
||||
|
||||
def test_resize(self):
|
||||
# Arrange
|
||||
image1 = Image.open(file1)
|
||||
image2 = Image.open(file2)
|
||||
new_size = (100, 100)
|
||||
|
||||
# Act
|
||||
image1 = image1.resize(new_size)
|
||||
image2 = image2.resize(new_size)
|
||||
|
||||
# Assert
|
||||
self.assertEqual(image1.size, new_size)
|
||||
self.assertEqual(image2.size, new_size)
|
||||
|
||||
def test_thumbnail(self):
|
||||
# Issue #619
|
||||
# Arrange
|
||||
image1 = Image.open(file1)
|
||||
image2 = Image.open(file2)
|
||||
new_size = (100, 100)
|
||||
|
||||
# Act
|
||||
image1.thumbnail(new_size)
|
||||
image2.thumbnail(new_size)
|
||||
|
||||
# Assert
|
||||
self.assertEqual(max(image1.size), max(new_size))
|
||||
self.assertEqual(max(image2.size), max(new_size))
|
||||
|
||||
def test_read_binary_preview(self):
|
||||
# Issue 302
|
||||
# open image with binary preview
|
||||
Image.open(file3)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
@ -6,9 +6,18 @@ from PIL import Image
|
|||
file = "Images/lena.fli"
|
||||
data = open(file, "rb").read()
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestFileFli(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
im = Image.open(file)
|
||||
im.load()
|
||||
assert_equal(im.mode, "P")
|
||||
assert_equal(im.size, (128, 128))
|
||||
assert_equal(im.format, "FLI")
|
||||
self.assertEqual(im.mode, "P")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "FLI")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,54 +1,59 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
codecs = dir(Image.core)
|
||||
|
||||
if "gif_encoder" not in codecs or "gif_decoder" not in codecs:
|
||||
skip("gif support not available") # can this happen?
|
||||
|
||||
# sample gif stream
|
||||
file = "Images/lena.gif"
|
||||
with open(file, "rb") as f:
|
||||
data = f.read()
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestFileGif(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if "gif_encoder" not in codecs or "gif_decoder" not in codecs:
|
||||
self.skipTest("gif support not available") # can this happen?
|
||||
|
||||
def test_sanity(self):
|
||||
im = Image.open(file)
|
||||
im.load()
|
||||
assert_equal(im.mode, "P")
|
||||
assert_equal(im.size, (128, 128))
|
||||
assert_equal(im.format, "GIF")
|
||||
self.assertEqual(im.mode, "P")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "GIF")
|
||||
|
||||
def test_optimize(self):
|
||||
from io import BytesIO
|
||||
|
||||
def test_optimize():
|
||||
def test(optimize):
|
||||
im = Image.new("L", (1, 1), 0)
|
||||
file = BytesIO()
|
||||
im.save(file, "GIF", optimize=optimize)
|
||||
return len(file.getvalue())
|
||||
assert_equal(test(0), 800)
|
||||
assert_equal(test(1), 38)
|
||||
self.assertEqual(test(0), 800)
|
||||
self.assertEqual(test(1), 38)
|
||||
|
||||
def test_roundtrip():
|
||||
out = tempfile('temp.gif')
|
||||
def test_roundtrip(self):
|
||||
out = self.tempfile('temp.gif')
|
||||
im = lena()
|
||||
im.save(out)
|
||||
reread = Image.open(out)
|
||||
|
||||
assert_image_similar(reread.convert('RGB'), im, 50)
|
||||
self.assert_image_similar(reread.convert('RGB'), im, 50)
|
||||
|
||||
def test_roundtrip2():
|
||||
#see https://github.com/python-imaging/Pillow/issues/403
|
||||
out = tempfile('temp.gif')
|
||||
def test_roundtrip2(self):
|
||||
# see https://github.com/python-pillow/Pillow/issues/403
|
||||
out = self.tempfile('temp.gif')
|
||||
im = Image.open('Images/lena.gif')
|
||||
im2 = im.copy()
|
||||
im2.save(out)
|
||||
reread = Image.open(out)
|
||||
|
||||
assert_image_similar(reread.convert('RGB'), lena(), 50)
|
||||
self.assert_image_similar(reread.convert('RGB'), lena(), 50)
|
||||
|
||||
|
||||
def test_palette_handling():
|
||||
# see https://github.com/python-imaging/Pillow/issues/513
|
||||
def test_palette_handling(self):
|
||||
# see https://github.com/python-pillow/Pillow/issues/513
|
||||
|
||||
im = Image.open('Images/lena.gif')
|
||||
im = im.convert('RGB')
|
||||
|
@ -56,18 +61,18 @@ def test_palette_handling():
|
|||
im = im.resize((100, 100), Image.ANTIALIAS)
|
||||
im2 = im.convert('P', palette=Image.ADAPTIVE, colors=256)
|
||||
|
||||
f = tempfile('temp.gif')
|
||||
f = self.tempfile('temp.gif')
|
||||
im2.save(f, optimize=True)
|
||||
|
||||
reloaded = Image.open(f)
|
||||
|
||||
assert_image_similar(im, reloaded.convert('RGB'), 10)
|
||||
self.assert_image_similar(im, reloaded.convert('RGB'), 10)
|
||||
|
||||
def test_palette_434():
|
||||
# see https://github.com/python-imaging/Pillow/issues/434
|
||||
def test_palette_434(self):
|
||||
# see https://github.com/python-pillow/Pillow/issues/434
|
||||
|
||||
def roundtrip(im, *args, **kwargs):
|
||||
out = tempfile('temp.gif')
|
||||
out = self.tempfile('temp.gif')
|
||||
im.save(out, *args, **kwargs)
|
||||
reloaded = Image.open(out)
|
||||
|
||||
|
@ -76,12 +81,16 @@ def test_palette_434():
|
|||
orig = "Tests/images/test.colors.gif"
|
||||
im = Image.open(orig)
|
||||
|
||||
assert_image_equal(*roundtrip(im))
|
||||
assert_image_equal(*roundtrip(im, optimize=True))
|
||||
self.assert_image_equal(*roundtrip(im))
|
||||
self.assert_image_equal(*roundtrip(im, optimize=True))
|
||||
|
||||
im = im.convert("RGB")
|
||||
# check automatic P conversion
|
||||
reloaded = roundtrip(im)[1].convert('RGB')
|
||||
assert_image_equal(im, reloaded)
|
||||
self.assert_image_equal(im, reloaded)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
@ -8,16 +8,19 @@ data = open(file, "rb").read()
|
|||
|
||||
enable_jpeg2k = hasattr(Image.core, 'jp2klib_version')
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestFileIcns(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
# Loading this icon by default should result in the largest size
|
||||
# (512x512@2x) being loaded
|
||||
im = Image.open(file)
|
||||
im.load()
|
||||
assert_equal(im.mode, "RGBA")
|
||||
assert_equal(im.size, (1024, 1024))
|
||||
assert_equal(im.format, "ICNS")
|
||||
self.assertEqual(im.mode, "RGBA")
|
||||
self.assertEqual(im.size, (1024, 1024))
|
||||
self.assertEqual(im.format, "ICNS")
|
||||
|
||||
def test_sizes():
|
||||
def test_sizes(self):
|
||||
# Check that we can load all of the sizes, and that the final pixel
|
||||
# dimensions are as expected
|
||||
im = Image.open(file)
|
||||
|
@ -27,10 +30,10 @@ def test_sizes():
|
|||
im2 = Image.open(file)
|
||||
im2.size = (w, h, r)
|
||||
im2.load()
|
||||
assert_equal(im2.mode, 'RGBA')
|
||||
assert_equal(im2.size, (wr, hr))
|
||||
self.assertEqual(im2.mode, 'RGBA')
|
||||
self.assertEqual(im2.size, (wr, hr))
|
||||
|
||||
def test_older_icon():
|
||||
def test_older_icon(self):
|
||||
# This icon was made with Icon Composer rather than iconutil; it still
|
||||
# uses PNG rather than JP2, however (since it was made on 10.9).
|
||||
im = Image.open('Tests/images/pillow2.icns')
|
||||
|
@ -40,10 +43,10 @@ def test_older_icon():
|
|||
im2 = Image.open('Tests/images/pillow2.icns')
|
||||
im2.size = (w, h, r)
|
||||
im2.load()
|
||||
assert_equal(im2.mode, 'RGBA')
|
||||
assert_equal(im2.size, (wr, hr))
|
||||
self.assertEqual(im2.mode, 'RGBA')
|
||||
self.assertEqual(im2.size, (wr, hr))
|
||||
|
||||
def test_jp2_icon():
|
||||
def test_jp2_icon(self):
|
||||
# This icon was made by using Uli Kusterer's oldiconutil to replace
|
||||
# the PNG images with JPEG 2000 ones. The advantage of doing this is
|
||||
# that OS X 10.5 supports JPEG 2000 but not PNG; some commercial
|
||||
|
@ -61,6 +64,11 @@ def test_jp2_icon():
|
|||
im2 = Image.open('Tests/images/pillow3.icns')
|
||||
im2.size = (w, h, r)
|
||||
im2.load()
|
||||
assert_equal(im2.mode, 'RGBA')
|
||||
assert_equal(im2.size, (wr, hr))
|
||||
self.assertEqual(im2.mode, 'RGBA')
|
||||
self.assertEqual(im2.size, (wr, hr))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
@ -6,9 +6,18 @@ from PIL import Image
|
|||
file = "Images/lena.ico"
|
||||
data = open(file, "rb").read()
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestFileIco(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
im = Image.open(file)
|
||||
im.load()
|
||||
assert_equal(im.mode, "RGBA")
|
||||
assert_equal(im.size, (16, 16))
|
||||
assert_equal(im.format, "ICO")
|
||||
self.assertEqual(im.mode, "RGBA")
|
||||
self.assertEqual(im.size, (16, 16))
|
||||
self.assertEqual(im.format, "ICO")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena, py3
|
||||
|
||||
import random
|
||||
from io import BytesIO
|
||||
|
||||
from PIL import Image
|
||||
from PIL import ImageFile
|
||||
|
||||
codecs = dir(Image.core)
|
||||
|
||||
if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs:
|
||||
skip("jpeg support not available")
|
||||
|
||||
test_file = "Images/lena.jpg"
|
||||
|
||||
def roundtrip(im, **options):
|
||||
|
||||
class TestFileJpeg(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs:
|
||||
self.skipTest("jpeg support not available")
|
||||
|
||||
def roundtrip(self, im, **options):
|
||||
out = BytesIO()
|
||||
im.save(out, "JPEG", **options)
|
||||
bytes = out.tell()
|
||||
|
@ -21,75 +26,78 @@ def roundtrip(im, **options):
|
|||
im.bytes = bytes # for testing only
|
||||
return im
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def test_sanity():
|
||||
def test_sanity(self):
|
||||
|
||||
# internal version number
|
||||
assert_match(Image.core.jpeglib_version, "\d+\.\d+$")
|
||||
self.assertRegexpMatches(Image.core.jpeglib_version, "\d+\.\d+$")
|
||||
|
||||
im = Image.open(test_file)
|
||||
im.load()
|
||||
assert_equal(im.mode, "RGB")
|
||||
assert_equal(im.size, (128, 128))
|
||||
assert_equal(im.format, "JPEG")
|
||||
self.assertEqual(im.mode, "RGB")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "JPEG")
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def test_app():
|
||||
def test_app(self):
|
||||
# Test APP/COM reader (@PIL135)
|
||||
im = Image.open(test_file)
|
||||
assert_equal(im.applist[0],
|
||||
self.assertEqual(
|
||||
im.applist[0],
|
||||
("APP0", b"JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00"))
|
||||
assert_equal(im.applist[1], ("COM", b"Python Imaging Library"))
|
||||
assert_equal(len(im.applist), 2)
|
||||
self.assertEqual(im.applist[1], ("COM", b"Python Imaging Library"))
|
||||
self.assertEqual(len(im.applist), 2)
|
||||
|
||||
def test_cmyk():
|
||||
def test_cmyk(self):
|
||||
# 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))]
|
||||
assert_true(c == 0.0 and m > 0.8 and y > 0.8 and k == 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))]
|
||||
assert_true(k > 0.9)
|
||||
self.assertGreater(k, 0.9)
|
||||
# roundtrip, and check again
|
||||
im = roundtrip(im)
|
||||
im = self.roundtrip(im)
|
||||
c, m, y, k = [x / 255.0 for x in im.getpixel((0, 0))]
|
||||
assert_true(c == 0.0 and m > 0.8 and y > 0.8 and k == 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))]
|
||||
assert_true(k > 0.9)
|
||||
self.assertGreater(k, 0.9)
|
||||
|
||||
def test_dpi():
|
||||
def test_dpi(self):
|
||||
def test(xdpi, ydpi=None):
|
||||
im = Image.open(test_file)
|
||||
im = roundtrip(im, dpi=(xdpi, ydpi or xdpi))
|
||||
im = self.roundtrip(im, dpi=(xdpi, ydpi or xdpi))
|
||||
return im.info.get("dpi")
|
||||
assert_equal(test(72), (72, 72))
|
||||
assert_equal(test(300), (300, 300))
|
||||
assert_equal(test(100, 200), (100, 200))
|
||||
assert_equal(test(0), None) # square pixels
|
||||
self.assertEqual(test(72), (72, 72))
|
||||
self.assertEqual(test(300), (300, 300))
|
||||
self.assertEqual(test(100, 200), (100, 200))
|
||||
self.assertEqual(test(0), None) # square pixels
|
||||
|
||||
def test_icc():
|
||||
def test_icc(self):
|
||||
# Test ICC support
|
||||
im1 = Image.open("Tests/images/rgb.jpg")
|
||||
icc_profile = im1.info["icc_profile"]
|
||||
assert_equal(len(icc_profile), 3144)
|
||||
self.assertEqual(len(icc_profile), 3144)
|
||||
# Roundtrip via physical file.
|
||||
f = tempfile("temp.jpg")
|
||||
f = self.tempfile("temp.jpg")
|
||||
im1.save(f, icc_profile=icc_profile)
|
||||
im2 = Image.open(f)
|
||||
assert_equal(im2.info.get("icc_profile"), icc_profile)
|
||||
self.assertEqual(im2.info.get("icc_profile"), icc_profile)
|
||||
# Roundtrip via memory buffer.
|
||||
im1 = roundtrip(lena())
|
||||
im2 = roundtrip(lena(), icc_profile=icc_profile)
|
||||
assert_image_equal(im1, im2)
|
||||
assert_false(im1.info.get("icc_profile"))
|
||||
assert_true(im2.info.get("icc_profile"))
|
||||
im1 = self.roundtrip(lena())
|
||||
im2 = self.roundtrip(lena(), icc_profile=icc_profile)
|
||||
self.assert_image_equal(im1, im2)
|
||||
self.assertFalse(im1.info.get("icc_profile"))
|
||||
self.assertTrue(im2.info.get("icc_profile"))
|
||||
|
||||
def test_icc_big():
|
||||
def test_icc_big(self):
|
||||
# Make sure that the "extra" support handles large blocks
|
||||
def test(n):
|
||||
# The ICC APP marker can store 65519 bytes per marker, so
|
||||
|
@ -97,43 +105,46 @@ def test_icc_big():
|
|||
# order issues.
|
||||
icc_profile = (b"Test"*int(n/4+1))[:n]
|
||||
assert len(icc_profile) == n # sanity
|
||||
im1 = roundtrip(lena(), icc_profile=icc_profile)
|
||||
assert_equal(im1.info.get("icc_profile"), icc_profile or None)
|
||||
test(0); test(1)
|
||||
test(3); test(4); test(5)
|
||||
im1 = self.roundtrip(lena(), icc_profile=icc_profile)
|
||||
self.assertEqual(im1.info.get("icc_profile"), icc_profile or None)
|
||||
test(0)
|
||||
test(1)
|
||||
test(3)
|
||||
test(4)
|
||||
test(5)
|
||||
test(65533-14) # full JPEG marker block
|
||||
test(65533-14+1) # full block plus one byte
|
||||
test(ImageFile.MAXBLOCK) # full buffer block
|
||||
test(ImageFile.MAXBLOCK+1) # full buffer block plus one byte
|
||||
test(ImageFile.MAXBLOCK*4+3) # large block
|
||||
|
||||
def test_optimize():
|
||||
im1 = roundtrip(lena())
|
||||
im2 = roundtrip(lena(), optimize=1)
|
||||
assert_image_equal(im1, im2)
|
||||
assert_true(im1.bytes >= im2.bytes)
|
||||
def test_optimize(self):
|
||||
im1 = self.roundtrip(lena())
|
||||
im2 = self.roundtrip(lena(), optimize=1)
|
||||
self.assert_image_equal(im1, im2)
|
||||
self.assertGreaterEqual(im1.bytes, im2.bytes)
|
||||
|
||||
def test_optimize_large_buffer():
|
||||
#https://github.com/python-imaging/Pillow/issues/148
|
||||
f = tempfile('temp.jpg')
|
||||
def test_optimize_large_buffer(self):
|
||||
# https://github.com/python-pillow/Pillow/issues/148
|
||||
f = self.tempfile('temp.jpg')
|
||||
# this requires ~ 1.5x Image.MAXBLOCK
|
||||
im = Image.new("RGB", (4096, 4096), 0xff3333)
|
||||
im.save(f, format="JPEG", optimize=True)
|
||||
|
||||
def test_progressive():
|
||||
im1 = roundtrip(lena())
|
||||
im2 = roundtrip(lena(), progressive=True)
|
||||
assert_image_equal(im1, im2)
|
||||
assert_true(im1.bytes >= im2.bytes)
|
||||
def test_progressive(self):
|
||||
im1 = self.roundtrip(lena())
|
||||
im2 = self.roundtrip(lena(), progressive=True)
|
||||
self.assert_image_equal(im1, im2)
|
||||
self.assertGreaterEqual(im1.bytes, im2.bytes)
|
||||
|
||||
def test_progressive_large_buffer():
|
||||
f = tempfile('temp.jpg')
|
||||
def test_progressive_large_buffer(self):
|
||||
f = self.tempfile('temp.jpg')
|
||||
# this requires ~ 1.5x Image.MAXBLOCK
|
||||
im = Image.new("RGB", (4096, 4096), 0xff3333)
|
||||
im.save(f, format="JPEG", progressive=True)
|
||||
|
||||
def test_progressive_large_buffer_highest_quality():
|
||||
f = tempfile('temp.jpg')
|
||||
def test_progressive_large_buffer_highest_quality(self):
|
||||
f = self.tempfile('temp.jpg')
|
||||
if py3:
|
||||
a = bytes(random.randint(0, 255) for _ in range(256 * 256 * 3))
|
||||
else:
|
||||
|
@ -142,68 +153,79 @@ def test_progressive_large_buffer_highest_quality():
|
|||
# this requires more bytes than pixels in the image
|
||||
im.save(f, format="JPEG", progressive=True, quality=100)
|
||||
|
||||
def test_large_exif():
|
||||
#https://github.com/python-imaging/Pillow/issues/148
|
||||
f = tempfile('temp.jpg')
|
||||
def test_large_exif(self):
|
||||
# https://github.com/python-pillow/Pillow/issues/148
|
||||
f = self.tempfile('temp.jpg')
|
||||
im = lena()
|
||||
im.save(f, 'JPEG', quality=90, exif=b"1"*65532)
|
||||
|
||||
def test_progressive_compat():
|
||||
im1 = roundtrip(lena())
|
||||
im2 = roundtrip(lena(), progressive=1)
|
||||
im3 = roundtrip(lena(), progression=1) # compatibility
|
||||
assert_image_equal(im1, im2)
|
||||
assert_image_equal(im1, im3)
|
||||
assert_false(im1.info.get("progressive"))
|
||||
assert_false(im1.info.get("progression"))
|
||||
assert_true(im2.info.get("progressive"))
|
||||
assert_true(im2.info.get("progression"))
|
||||
assert_true(im3.info.get("progressive"))
|
||||
assert_true(im3.info.get("progression"))
|
||||
def test_progressive_compat(self):
|
||||
im1 = self.roundtrip(lena())
|
||||
im2 = self.roundtrip(lena(), progressive=1)
|
||||
im3 = self.roundtrip(lena(), progression=1) # compatibility
|
||||
self.assert_image_equal(im1, im2)
|
||||
self.assert_image_equal(im1, im3)
|
||||
self.assertFalse(im1.info.get("progressive"))
|
||||
self.assertFalse(im1.info.get("progression"))
|
||||
self.assertTrue(im2.info.get("progressive"))
|
||||
self.assertTrue(im2.info.get("progression"))
|
||||
self.assertTrue(im3.info.get("progressive"))
|
||||
self.assertTrue(im3.info.get("progression"))
|
||||
|
||||
def test_quality():
|
||||
im1 = roundtrip(lena())
|
||||
im2 = roundtrip(lena(), quality=50)
|
||||
assert_image(im1, im2.mode, im2.size)
|
||||
assert_true(im1.bytes >= im2.bytes)
|
||||
def test_quality(self):
|
||||
im1 = self.roundtrip(lena())
|
||||
im2 = self.roundtrip(lena(), quality=50)
|
||||
self.assert_image(im1, im2.mode, im2.size)
|
||||
self.assertGreaterEqual(im1.bytes, im2.bytes)
|
||||
|
||||
def test_smooth():
|
||||
im1 = roundtrip(lena())
|
||||
im2 = roundtrip(lena(), smooth=100)
|
||||
assert_image(im1, im2.mode, im2.size)
|
||||
def test_smooth(self):
|
||||
im1 = self.roundtrip(lena())
|
||||
im2 = self.roundtrip(lena(), smooth=100)
|
||||
self.assert_image(im1, im2.mode, im2.size)
|
||||
|
||||
def test_subsampling():
|
||||
def test_subsampling(self):
|
||||
def getsampling(im):
|
||||
layer = im.layer
|
||||
return layer[0][1:3] + layer[1][1:3] + layer[2][1:3]
|
||||
# experimental API
|
||||
im = roundtrip(lena(), subsampling=-1) # default
|
||||
assert_equal(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||
im = roundtrip(lena(), subsampling=0) # 4:4:4
|
||||
assert_equal(getsampling(im), (1, 1, 1, 1, 1, 1))
|
||||
im = roundtrip(lena(), subsampling=1) # 4:2:2
|
||||
assert_equal(getsampling(im), (2, 1, 1, 1, 1, 1))
|
||||
im = roundtrip(lena(), subsampling=2) # 4:1:1
|
||||
assert_equal(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||
im = roundtrip(lena(), subsampling=3) # default (undefined)
|
||||
assert_equal(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||
im = self.roundtrip(lena(), subsampling=-1) # default
|
||||
self.assertEqual(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||
im = self.roundtrip(lena(), subsampling=0) # 4:4:4
|
||||
self.assertEqual(getsampling(im), (1, 1, 1, 1, 1, 1))
|
||||
im = self.roundtrip(lena(), subsampling=1) # 4:2:2
|
||||
self.assertEqual(getsampling(im), (2, 1, 1, 1, 1, 1))
|
||||
im = self.roundtrip(lena(), subsampling=2) # 4:1:1
|
||||
self.assertEqual(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||
im = self.roundtrip(lena(), subsampling=3) # default (undefined)
|
||||
self.assertEqual(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||
|
||||
im = roundtrip(lena(), subsampling="4:4:4")
|
||||
assert_equal(getsampling(im), (1, 1, 1, 1, 1, 1))
|
||||
im = roundtrip(lena(), subsampling="4:2:2")
|
||||
assert_equal(getsampling(im), (2, 1, 1, 1, 1, 1))
|
||||
im = roundtrip(lena(), subsampling="4:1:1")
|
||||
assert_equal(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||
im = self.roundtrip(lena(), subsampling="4:4:4")
|
||||
self.assertEqual(getsampling(im), (1, 1, 1, 1, 1, 1))
|
||||
im = self.roundtrip(lena(), subsampling="4:2:2")
|
||||
self.assertEqual(getsampling(im), (2, 1, 1, 1, 1, 1))
|
||||
im = self.roundtrip(lena(), subsampling="4:1:1")
|
||||
self.assertEqual(getsampling(im), (2, 2, 1, 1, 1, 1))
|
||||
|
||||
assert_exception(TypeError, lambda: roundtrip(lena(), subsampling="1:1:1"))
|
||||
self.assertRaises(
|
||||
TypeError, lambda: self.roundtrip(lena(), subsampling="1:1:1"))
|
||||
|
||||
def test_exif():
|
||||
def test_exif(self):
|
||||
im = Image.open("Tests/images/pil_sample_rgb.jpg")
|
||||
info = im._getexif()
|
||||
assert_equal(info[305], 'Adobe Photoshop CS Macintosh')
|
||||
self.assertEqual(info[305], 'Adobe Photoshop CS Macintosh')
|
||||
|
||||
|
||||
def test_quality_keep():
|
||||
def test_quality_keep(self):
|
||||
im = Image.open("Images/lena.jpg")
|
||||
f = tempfile('temp.jpg')
|
||||
assert_no_exception(lambda: im.save(f, quality='keep'))
|
||||
f = self.tempfile('temp.jpg')
|
||||
im.save(f, quality='keep')
|
||||
|
||||
def test_junk_jpeg_header(self):
|
||||
# https://github.com/python-pillow/Pillow/issues/630
|
||||
filename = "Tests/images/junk_jpeg_header.jpg"
|
||||
Image.open(filename)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
from PIL import ImageFile
|
||||
from io import BytesIO
|
||||
|
||||
codecs = dir(Image.core)
|
||||
|
||||
if "jpeg2k_encoder" not in codecs or "jpeg2k_decoder" not in codecs:
|
||||
skip('JPEG 2000 support not available')
|
||||
|
||||
# OpenJPEG 2.0.0 outputs this debugging message sometimes; we should
|
||||
# ignore it---it doesn't represent a test failure.
|
||||
ignore('Not enough memory to handle tile data')
|
||||
|
||||
test_card = Image.open('Tests/images/test-card.png')
|
||||
test_card.load()
|
||||
|
||||
def roundtrip(im, **options):
|
||||
# OpenJPEG 2.0.0 outputs this debugging message sometimes; we should
|
||||
# ignore it---it doesn't represent a test failure.
|
||||
# 'Not enough memory to handle tile data'
|
||||
|
||||
|
||||
class TestFileJpeg2k(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if "jpeg2k_encoder" not in codecs or "jpeg2k_decoder" not in codecs:
|
||||
self.skipTest('JPEG 2000 support not available')
|
||||
|
||||
def roundtrip(self, im, **options):
|
||||
out = BytesIO()
|
||||
im.save(out, "JPEG2000", **options)
|
||||
bytes = out.tell()
|
||||
|
@ -25,74 +29,68 @@ def roundtrip(im, **options):
|
|||
im.load()
|
||||
return im
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def test_sanity():
|
||||
def test_sanity(self):
|
||||
# Internal version number
|
||||
assert_match(Image.core.jp2klib_version, '\d+\.\d+\.\d+$')
|
||||
self.assertRegexpMatches(Image.core.jp2klib_version, '\d+\.\d+\.\d+$')
|
||||
|
||||
im = Image.open('Tests/images/test-card-lossless.jp2')
|
||||
im.load()
|
||||
assert_equal(im.mode, 'RGB')
|
||||
assert_equal(im.size, (640, 480))
|
||||
assert_equal(im.format, 'JPEG2000')
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
self.assertEqual(im.mode, 'RGB')
|
||||
self.assertEqual(im.size, (640, 480))
|
||||
self.assertEqual(im.format, 'JPEG2000')
|
||||
|
||||
# These two test pre-written JPEG 2000 files that were not written with
|
||||
# PIL (they were made using Adobe Photoshop)
|
||||
|
||||
def test_lossless():
|
||||
def test_lossless(self):
|
||||
im = Image.open('Tests/images/test-card-lossless.jp2')
|
||||
im.load()
|
||||
im.save('/tmp/test-card.png')
|
||||
assert_image_similar(im, test_card, 1.0e-3)
|
||||
self.assert_image_similar(im, test_card, 1.0e-3)
|
||||
|
||||
def test_lossy_tiled():
|
||||
def test_lossy_tiled(self):
|
||||
im = Image.open('Tests/images/test-card-lossy-tiled.jp2')
|
||||
im.load()
|
||||
assert_image_similar(im, test_card, 2.0)
|
||||
self.assert_image_similar(im, test_card, 2.0)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def test_lossless_rt(self):
|
||||
im = self.roundtrip(test_card)
|
||||
self.assert_image_equal(im, test_card)
|
||||
|
||||
def test_lossless_rt():
|
||||
im = roundtrip(test_card)
|
||||
assert_image_equal(im, test_card)
|
||||
def test_lossy_rt(self):
|
||||
im = self.roundtrip(test_card, quality_layers=[20])
|
||||
self.assert_image_similar(im, test_card, 2.0)
|
||||
|
||||
def test_lossy_rt():
|
||||
im = roundtrip(test_card, quality_layers=[20])
|
||||
assert_image_similar(im, test_card, 2.0)
|
||||
def test_tiled_rt(self):
|
||||
im = self.roundtrip(test_card, tile_size=(128, 128))
|
||||
self.assert_image_equal(im, test_card)
|
||||
|
||||
def test_tiled_rt():
|
||||
im = roundtrip(test_card, tile_size=(128, 128))
|
||||
assert_image_equal(im, test_card)
|
||||
def test_tiled_offset_rt(self):
|
||||
im = self.roundtrip(
|
||||
test_card, tile_size=(128, 128),
|
||||
tile_offset=(0, 0), offset=(32, 32))
|
||||
self.assert_image_equal(im, test_card)
|
||||
|
||||
def test_tiled_offset_rt():
|
||||
im = roundtrip(test_card, tile_size=(128, 128), tile_offset=(0, 0),
|
||||
offset=(32, 32))
|
||||
assert_image_equal(im, test_card)
|
||||
def test_irreversible_rt(self):
|
||||
im = self.roundtrip(test_card, irreversible=True, quality_layers=[20])
|
||||
self.assert_image_similar(im, test_card, 2.0)
|
||||
|
||||
def test_irreversible_rt():
|
||||
im = roundtrip(test_card, irreversible=True, quality_layers=[20])
|
||||
assert_image_similar(im, test_card, 2.0)
|
||||
def test_prog_qual_rt(self):
|
||||
im = self.roundtrip(
|
||||
test_card, quality_layers=[60, 40, 20], progression='LRCP')
|
||||
self.assert_image_similar(im, test_card, 2.0)
|
||||
|
||||
def test_prog_qual_rt():
|
||||
im = roundtrip(test_card, quality_layers=[60, 40, 20], progression='LRCP')
|
||||
assert_image_similar(im, test_card, 2.0)
|
||||
def test_prog_res_rt(self):
|
||||
im = self.roundtrip(test_card, num_resolutions=8, progression='RLCP')
|
||||
self.assert_image_equal(im, test_card)
|
||||
|
||||
def test_prog_res_rt():
|
||||
im = roundtrip(test_card, num_resolutions=8, progression='RLCP')
|
||||
assert_image_equal(im, test_card)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def test_reduce():
|
||||
def test_reduce(self):
|
||||
im = Image.open('Tests/images/test-card-lossless.jp2')
|
||||
im.reduce = 2
|
||||
im.load()
|
||||
assert_equal(im.size, (160, 120))
|
||||
self.assertEqual(im.size, (160, 120))
|
||||
|
||||
def test_layers():
|
||||
def test_layers(self):
|
||||
out = BytesIO()
|
||||
test_card.save(out, 'JPEG2000', quality_layers=[100, 50, 10],
|
||||
progression='LRCP')
|
||||
|
@ -101,10 +99,16 @@ def test_layers():
|
|||
im = Image.open(out)
|
||||
im.layers = 1
|
||||
im.load()
|
||||
assert_image_similar(im, test_card, 13)
|
||||
self.assert_image_similar(im, test_card, 13)
|
||||
|
||||
out.seek(0)
|
||||
im = Image.open(out)
|
||||
im.layers = 3
|
||||
im.load()
|
||||
assert_image_similar(im, test_card, 0.4)
|
||||
self.assert_image_similar(im, test_card, 0.4)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,57 +1,62 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena, py3
|
||||
|
||||
import os
|
||||
|
||||
from PIL import Image, TiffImagePlugin
|
||||
|
||||
|
||||
class TestFileLibTiff(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
codecs = dir(Image.core)
|
||||
|
||||
if "libtiff_encoder" not in codecs or "libtiff_decoder" not in codecs:
|
||||
skip("tiff support not available")
|
||||
self.skipTest("tiff support not available")
|
||||
|
||||
def _assert_noerr(im):
|
||||
def _assert_noerr(self, im):
|
||||
"""Helper tests that assert basic sanity about the g4 tiff reading"""
|
||||
# 1 bit
|
||||
assert_equal(im.mode, "1")
|
||||
self.assertEqual(im.mode, "1")
|
||||
|
||||
# Does the data actually load
|
||||
assert_no_exception(lambda: im.load())
|
||||
assert_no_exception(lambda: im.getdata())
|
||||
im.load()
|
||||
im.getdata()
|
||||
|
||||
try:
|
||||
assert_equal(im._compression, 'group4')
|
||||
self.assertEqual(im._compression, 'group4')
|
||||
except:
|
||||
print("No _compression")
|
||||
print (dir(im))
|
||||
|
||||
# can we write it back out, in a different form.
|
||||
out = tempfile("temp.png")
|
||||
assert_no_exception(lambda: im.save(out))
|
||||
out = self.tempfile("temp.png")
|
||||
im.save(out)
|
||||
|
||||
def test_g4_tiff():
|
||||
def test_g4_tiff(self):
|
||||
"""Test the ordinary file path load path"""
|
||||
|
||||
file = "Tests/images/lena_g4_500.tif"
|
||||
im = Image.open(file)
|
||||
|
||||
assert_equal(im.size, (500,500))
|
||||
_assert_noerr(im)
|
||||
self.assertEqual(im.size, (500, 500))
|
||||
self._assert_noerr(im)
|
||||
|
||||
def test_g4_large():
|
||||
def test_g4_large(self):
|
||||
file = "Tests/images/pport_g4.tif"
|
||||
im = Image.open(file)
|
||||
_assert_noerr(im)
|
||||
self._assert_noerr(im)
|
||||
|
||||
def test_g4_tiff_file():
|
||||
def test_g4_tiff_file(self):
|
||||
"""Testing the string load path"""
|
||||
|
||||
file = "Tests/images/lena_g4_500.tif"
|
||||
with open(file, 'rb') as f:
|
||||
im = Image.open(f)
|
||||
|
||||
assert_equal(im.size, (500,500))
|
||||
_assert_noerr(im)
|
||||
self.assertEqual(im.size, (500, 500))
|
||||
self._assert_noerr(im)
|
||||
|
||||
def test_g4_tiff_bytesio():
|
||||
def test_g4_tiff_bytesio(self):
|
||||
"""Testing the stringio loading code path"""
|
||||
from io import BytesIO
|
||||
file = "Tests/images/lena_g4_500.tif"
|
||||
|
@ -61,57 +66,58 @@ def test_g4_tiff_bytesio():
|
|||
s.seek(0)
|
||||
im = Image.open(s)
|
||||
|
||||
assert_equal(im.size, (500,500))
|
||||
_assert_noerr(im)
|
||||
self.assertEqual(im.size, (500, 500))
|
||||
self._assert_noerr(im)
|
||||
|
||||
def test_g4_eq_png():
|
||||
def test_g4_eq_png(self):
|
||||
""" Checking that we're actually getting the data that we expect"""
|
||||
png = Image.open('Tests/images/lena_bw_500.png')
|
||||
g4 = Image.open('Tests/images/lena_g4_500.tif')
|
||||
|
||||
assert_image_equal(g4, png)
|
||||
self.assert_image_equal(g4, png)
|
||||
|
||||
# see https://github.com/python-imaging/Pillow/issues/279
|
||||
def test_g4_fillorder_eq_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')
|
||||
|
||||
assert_image_equal(g4, png)
|
||||
self.assert_image_equal(g4, png)
|
||||
|
||||
def test_g4_write():
|
||||
def test_g4_write(self):
|
||||
"""Checking to see that the saved image is the same as what we wrote"""
|
||||
file = "Tests/images/lena_g4_500.tif"
|
||||
orig = Image.open(file)
|
||||
|
||||
out = tempfile("temp.tif")
|
||||
out = self.tempfile("temp.tif")
|
||||
rot = orig.transpose(Image.ROTATE_90)
|
||||
assert_equal(rot.size,(500,500))
|
||||
self.assertEqual(rot.size, (500, 500))
|
||||
rot.save(out)
|
||||
|
||||
reread = Image.open(out)
|
||||
assert_equal(reread.size,(500,500))
|
||||
_assert_noerr(reread)
|
||||
assert_image_equal(reread, rot)
|
||||
assert_equal(reread.info['compression'], 'group4')
|
||||
self.assertEqual(reread.size, (500, 500))
|
||||
self._assert_noerr(reread)
|
||||
self.assert_image_equal(reread, rot)
|
||||
self.assertEqual(reread.info['compression'], 'group4')
|
||||
|
||||
assert_equal(reread.info['compression'], orig.info['compression'])
|
||||
self.assertEqual(reread.info['compression'], orig.info['compression'])
|
||||
|
||||
assert_false(orig.tobytes() == reread.tobytes())
|
||||
self.assertNotEqual(orig.tobytes(), reread.tobytes())
|
||||
|
||||
def test_adobe_deflate_tiff():
|
||||
def test_adobe_deflate_tiff(self):
|
||||
file = "Tests/images/tiff_adobe_deflate.tif"
|
||||
im = Image.open(file)
|
||||
|
||||
assert_equal(im.mode, "RGB")
|
||||
assert_equal(im.size, (278, 374))
|
||||
assert_equal(im.tile[0][:3], ('tiff_adobe_deflate', (0, 0, 278, 374), 0))
|
||||
assert_no_exception(lambda: im.load())
|
||||
self.assertEqual(im.mode, "RGB")
|
||||
self.assertEqual(im.size, (278, 374))
|
||||
self.assertEqual(
|
||||
im.tile[0][:3], ('tiff_adobe_deflate', (0, 0, 278, 374), 0))
|
||||
im.load()
|
||||
|
||||
def test_write_metadata():
|
||||
def test_write_metadata(self):
|
||||
""" Test metadata writing through libtiff """
|
||||
img = Image.open('Tests/images/lena_g4.tif')
|
||||
f = tempfile('temp.tiff')
|
||||
f = self.tempfile('temp.tiff')
|
||||
|
||||
img.save(f, tiffinfo=img.tag)
|
||||
|
||||
|
@ -120,100 +126,106 @@ def test_write_metadata():
|
|||
original = img.tag.named()
|
||||
reloaded = loaded.tag.named()
|
||||
|
||||
# PhotometricInterpretation is set from SAVE_INFO, not the original image.
|
||||
ignored = ['StripByteCounts', 'RowsPerStrip', 'PageNumber', 'PhotometricInterpretation']
|
||||
# PhotometricInterpretation is set from SAVE_INFO,
|
||||
# not the original image.
|
||||
ignored = [
|
||||
'StripByteCounts', 'RowsPerStrip',
|
||||
'PageNumber', 'PhotometricInterpretation']
|
||||
|
||||
for tag, value in reloaded.items():
|
||||
if tag not in ignored:
|
||||
if tag.endswith('Resolution'):
|
||||
val = original[tag]
|
||||
assert_almost_equal(val[0][0]/val[0][1], value[0][0]/value[0][1],
|
||||
self.assert_almost_equal(
|
||||
val[0][0]/val[0][1], value[0][0]/value[0][1],
|
||||
msg="%s didn't roundtrip" % tag)
|
||||
else:
|
||||
assert_equal(original[tag], value, "%s didn't roundtrip" % tag)
|
||||
self.assertEqual(
|
||||
original[tag], value, "%s didn't roundtrip" % tag)
|
||||
|
||||
for tag, value in original.items():
|
||||
if tag not in ignored:
|
||||
if tag.endswith('Resolution'):
|
||||
val = reloaded[tag]
|
||||
assert_almost_equal(val[0][0]/val[0][1], value[0][0]/value[0][1],
|
||||
self.assert_almost_equal(
|
||||
val[0][0]/val[0][1], value[0][0]/value[0][1],
|
||||
msg="%s didn't roundtrip" % tag)
|
||||
else:
|
||||
assert_equal(value, reloaded[tag], "%s didn't roundtrip" % tag)
|
||||
self.assertEqual(
|
||||
value, reloaded[tag], "%s didn't roundtrip" % tag)
|
||||
|
||||
|
||||
def test_g3_compression():
|
||||
def test_g3_compression(self):
|
||||
i = Image.open('Tests/images/lena_g4_500.tif')
|
||||
out = tempfile("temp.tif")
|
||||
out = self.tempfile("temp.tif")
|
||||
i.save(out, compression='group3')
|
||||
|
||||
reread = Image.open(out)
|
||||
assert_equal(reread.info['compression'], 'group3')
|
||||
assert_image_equal(reread, i)
|
||||
self.assertEqual(reread.info['compression'], 'group3')
|
||||
self.assert_image_equal(reread, i)
|
||||
|
||||
def test_little_endian():
|
||||
def test_little_endian(self):
|
||||
im = Image.open('Tests/images/16bit.deflate.tif')
|
||||
assert_equal(im.getpixel((0,0)), 480)
|
||||
assert_equal(im.mode, 'I;16')
|
||||
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:
|
||||
assert_equal(b[0], ord(b'\xe0'))
|
||||
assert_equal(b[1], ord(b'\x01'))
|
||||
self.assertEqual(b[0], ord(b'\xe0'))
|
||||
self.assertEqual(b[1], ord(b'\x01'))
|
||||
else:
|
||||
assert_equal(b[0], b'\xe0')
|
||||
assert_equal(b[1], b'\x01')
|
||||
self.assertEqual(b[0], b'\xe0')
|
||||
self.assertEqual(b[1], b'\x01')
|
||||
|
||||
|
||||
out = tempfile("temp.tif")
|
||||
out = self.tempfile("temp.tif")
|
||||
# out = "temp.le.tif"
|
||||
im.save(out)
|
||||
reread = Image.open(out)
|
||||
|
||||
assert_equal(reread.info['compression'], im.info['compression'])
|
||||
assert_equal(reread.getpixel((0,0)), 480)
|
||||
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():
|
||||
def test_big_endian(self):
|
||||
im = Image.open('Tests/images/16bit.MM.deflate.tif')
|
||||
|
||||
assert_equal(im.getpixel((0,0)), 480)
|
||||
assert_equal(im.mode, 'I;16B')
|
||||
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:
|
||||
assert_equal(b[0], ord(b'\x01'))
|
||||
assert_equal(b[1], ord(b'\xe0'))
|
||||
self.assertEqual(b[0], ord(b'\x01'))
|
||||
self.assertEqual(b[1], ord(b'\xe0'))
|
||||
else:
|
||||
assert_equal(b[0], b'\x01')
|
||||
assert_equal(b[1], b'\xe0')
|
||||
self.assertEqual(b[0], b'\x01')
|
||||
self.assertEqual(b[1], b'\xe0')
|
||||
|
||||
out = tempfile("temp.tif")
|
||||
out = self.tempfile("temp.tif")
|
||||
im.save(out)
|
||||
reread = Image.open(out)
|
||||
|
||||
assert_equal(reread.info['compression'], im.info['compression'])
|
||||
assert_equal(reread.getpixel((0,0)), 480)
|
||||
self.assertEqual(reread.info['compression'], im.info['compression'])
|
||||
self.assertEqual(reread.getpixel((0, 0)), 480)
|
||||
|
||||
def test_g4_string_info():
|
||||
def test_g4_string_info(self):
|
||||
"""Tests String data in info directory"""
|
||||
file = "Tests/images/lena_g4_500.tif"
|
||||
orig = Image.open(file)
|
||||
|
||||
out = tempfile("temp.tif")
|
||||
out = self.tempfile("temp.tif")
|
||||
|
||||
orig.tag[269] = 'temp.tif'
|
||||
orig.save(out)
|
||||
|
||||
reread = Image.open(out)
|
||||
assert_equal('temp.tif', reread.tag[269])
|
||||
self.assertEqual('temp.tif', reread.tag[269])
|
||||
|
||||
def test_12bit_rawmode():
|
||||
""" Are we generating the same interpretation of the image as Imagemagick is? """
|
||||
def test_12bit_rawmode(self):
|
||||
""" Are we generating the same interpretation
|
||||
of the image as Imagemagick is? """
|
||||
TiffImagePlugin.READ_LIBTIFF = True
|
||||
# Image.DEBUG = True
|
||||
im = Image.open('Tests/images/12bit.cropped.tif')
|
||||
|
@ -236,12 +248,13 @@ def test_12bit_rawmode():
|
|||
print (im2.getpixel((0, 1)))
|
||||
print (im2.getpixel((0, 2)))
|
||||
|
||||
assert_image_equal(im, im2)
|
||||
self.assert_image_equal(im, im2)
|
||||
|
||||
def test_blur():
|
||||
# test case from irc, how to do blur on b/w image and save to compressed tif.
|
||||
def test_blur(self):
|
||||
# test case from irc, how to do blur on b/w image
|
||||
# and save to compressed tif.
|
||||
from PIL import ImageFilter
|
||||
out = tempfile('temp.tif')
|
||||
out = self.tempfile('temp.tif')
|
||||
im = Image.open('Tests/images/pport_g4.tif')
|
||||
im = im.convert('L')
|
||||
|
||||
|
@ -251,58 +264,55 @@ def test_blur():
|
|||
im2 = Image.open(out)
|
||||
im2.load()
|
||||
|
||||
assert_image_equal(im, im2)
|
||||
self.assert_image_equal(im, im2)
|
||||
|
||||
|
||||
def test_compressions():
|
||||
def test_compressions(self):
|
||||
im = lena('RGB')
|
||||
out = tempfile('temp.tif')
|
||||
|
||||
TiffImagePlugin.READ_LIBTIFF = True
|
||||
TiffImagePlugin.WRITE_LIBTIFF = True
|
||||
out = self.tempfile('temp.tif')
|
||||
|
||||
for compression in ('packbits', 'tiff_lzw'):
|
||||
im.save(out, compression=compression)
|
||||
im2 = Image.open(out)
|
||||
assert_image_equal(im, im2)
|
||||
self.assert_image_equal(im, im2)
|
||||
|
||||
im.save(out, compression='jpeg')
|
||||
im2 = Image.open(out)
|
||||
assert_image_similar(im, im2, 30)
|
||||
self.assert_image_similar(im, im2, 30)
|
||||
|
||||
TiffImagePlugin.READ_LIBTIFF = False
|
||||
TiffImagePlugin.WRITE_LIBTIFF = False
|
||||
|
||||
|
||||
|
||||
|
||||
def test_cmyk_save():
|
||||
def test_cmyk_save(self):
|
||||
im = lena('CMYK')
|
||||
out = tempfile('temp.tif')
|
||||
out = self.tempfile('temp.tif')
|
||||
|
||||
im.save(out, compression='tiff_adobe_deflate')
|
||||
im2 = Image.open(out)
|
||||
assert_image_equal(im, im2)
|
||||
self.assert_image_equal(im, im2)
|
||||
|
||||
def xtest_bw_compression_wRGB():
|
||||
""" This test passes, but when running all tests causes a failure due to
|
||||
output on stderr from the error thrown by libtiff. We need to capture that
|
||||
but not now"""
|
||||
def xtest_bw_compression_wRGB(self):
|
||||
""" This test passes, but when running all tests causes a failure due
|
||||
to output on stderr from the error thrown by libtiff. We need to
|
||||
capture that but not now"""
|
||||
|
||||
im = lena('RGB')
|
||||
out = tempfile('temp.tif')
|
||||
out = self.tempfile('temp.tif')
|
||||
|
||||
assert_exception(IOError, lambda: im.save(out, compression='tiff_ccitt'))
|
||||
assert_exception(IOError, lambda: im.save(out, compression='group3'))
|
||||
assert_exception(IOError, lambda: im.save(out, compression='group4'))
|
||||
self.assertRaises(
|
||||
IOError, lambda: im.save(out, compression='tiff_ccitt'))
|
||||
self.assertRaises(IOError, lambda: im.save(out, compression='group3'))
|
||||
self.assertRaises(IOError, lambda: im.save(out, compression='group4'))
|
||||
|
||||
def test_fp_leak():
|
||||
def test_fp_leak(self):
|
||||
im = Image.open("Tests/images/lena_g4_500.tif")
|
||||
fn = im.fp.fileno()
|
||||
|
||||
assert_no_exception(lambda: os.fstat(fn))
|
||||
os.fstat(fn)
|
||||
im.load() # this should close it.
|
||||
assert_exception(OSError, lambda: os.fstat(fn))
|
||||
self.assertRaises(OSError, lambda: os.fstat(fn))
|
||||
im = None # this should force even more closed.
|
||||
assert_exception(OSError, lambda: os.fstat(fn))
|
||||
assert_exception(OSError, lambda: os.close(fn))
|
||||
self.assertRaises(OSError, lambda: os.fstat(fn))
|
||||
self.assertRaises(OSError, lambda: os.close(fn))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from tester import *
|
||||
from helper import unittest, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from test_file_libtiff import _assert_noerr
|
||||
from test_file_libtiff import TestFileLibTiff
|
||||
|
||||
codecs = dir(Image.core)
|
||||
|
||||
if "libtiff_encoder" not in codecs or "libtiff_decoder" not in codecs:
|
||||
skip("tiff support not available")
|
||||
class TestFileLibTiffSmall(TestFileLibTiff):
|
||||
|
||||
# Inherits TestFileLibTiff's setUp() and self._assert_noerr()
|
||||
|
||||
""" The small lena image was failing on open in the libtiff
|
||||
decoder because the file pointer was set to the wrong place
|
||||
|
@ -17,18 +17,17 @@ if "libtiff_encoder" not in codecs or "libtiff_decoder" not in codecs:
|
|||
file just before reading in libtiff. These tests remain
|
||||
to ensure that it stays fixed. """
|
||||
|
||||
|
||||
def test_g4_lena_file():
|
||||
def test_g4_lena_file(self):
|
||||
"""Testing the open file load path"""
|
||||
|
||||
file = "Tests/images/lena_g4.tif"
|
||||
with open(file, 'rb') as f:
|
||||
im = Image.open(f)
|
||||
|
||||
assert_equal(im.size, (128,128))
|
||||
_assert_noerr(im)
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self._assert_noerr(im)
|
||||
|
||||
def test_g4_lena_bytesio():
|
||||
def test_g4_lena_bytesio(self):
|
||||
"""Testing the bytesio loading code path"""
|
||||
from io import BytesIO
|
||||
file = "Tests/images/lena_g4.tif"
|
||||
|
@ -38,15 +37,20 @@ def test_g4_lena_bytesio():
|
|||
s.seek(0)
|
||||
im = Image.open(s)
|
||||
|
||||
assert_equal(im.size, (128,128))
|
||||
_assert_noerr(im)
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self._assert_noerr(im)
|
||||
|
||||
def test_g4_lena():
|
||||
def test_g4_lena(self):
|
||||
"""The 128x128 lena image fails for some reason. Investigating"""
|
||||
|
||||
file = "Tests/images/lena_g4.tif"
|
||||
im = Image.open(file)
|
||||
|
||||
assert_equal(im.size, (128,128))
|
||||
_assert_noerr(im)
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self._assert_noerr(im)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,15 +1,24 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
|
||||
file = tempfile("temp.msp")
|
||||
class TestFileMsp(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
file = self.tempfile("temp.msp")
|
||||
|
||||
lena("1").save(file)
|
||||
|
||||
im = Image.open(file)
|
||||
im.load()
|
||||
assert_equal(im.mode, "1")
|
||||
assert_equal(im.size, (128, 128))
|
||||
assert_equal(im.format, "MSP")
|
||||
self.assertEqual(im.mode, "1")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "MSP")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,40 +1,47 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
def _roundtrip(im):
|
||||
f = tempfile("temp.pcx")
|
||||
class TestFilePcx(PillowTestCase):
|
||||
|
||||
def _roundtrip(self, im):
|
||||
f = self.tempfile("temp.pcx")
|
||||
im.save(f)
|
||||
im2 = Image.open(f)
|
||||
|
||||
assert_equal(im2.mode, im.mode)
|
||||
assert_equal(im2.size, im.size)
|
||||
assert_equal(im2.format, "PCX")
|
||||
assert_image_equal(im2, im)
|
||||
self.assertEqual(im2.mode, im.mode)
|
||||
self.assertEqual(im2.size, im.size)
|
||||
self.assertEqual(im2.format, "PCX")
|
||||
self.assert_image_equal(im2, im)
|
||||
|
||||
def test_sanity():
|
||||
def test_sanity(self):
|
||||
for mode in ('1', 'L', 'P', 'RGB'):
|
||||
_roundtrip(lena(mode))
|
||||
self._roundtrip(lena(mode))
|
||||
|
||||
def test_odd():
|
||||
def test_odd(self):
|
||||
# see issue #523, odd sized images should have a stride that's even.
|
||||
# not that imagemagick or gimp write pcx that way.
|
||||
# we were not handling properly.
|
||||
for mode in ('1', 'L', 'P', 'RGB'):
|
||||
# larger, odd sized images are better here to ensure that
|
||||
# we handle interrupted scan lines properly.
|
||||
_roundtrip(lena(mode).resize((511,511)))
|
||||
self._roundtrip(lena(mode).resize((511, 511)))
|
||||
|
||||
|
||||
def test_pil184():
|
||||
def test_pil184(self):
|
||||
# Check reading of files where xmin/xmax is not zero.
|
||||
|
||||
file = "Tests/images/pil184.pcx"
|
||||
im = Image.open(file)
|
||||
|
||||
assert_equal(im.size, (447, 144))
|
||||
assert_equal(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.
|
||||
assert_equal(im.histogram()[0] + im.histogram()[255], 447*144)
|
||||
self.assertEqual(im.histogram()[0] + im.histogram()[255], 447*144)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
59
Tests/test_file_pdf.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
import os.path
|
||||
|
||||
|
||||
class TestFilePdf(PillowTestCase):
|
||||
|
||||
def helper_save_as_pdf(self, mode):
|
||||
# Arrange
|
||||
im = lena(mode)
|
||||
outfile = self.tempfile("temp_" + mode + ".pdf")
|
||||
|
||||
# Act
|
||||
im.save(outfile)
|
||||
|
||||
# Assert
|
||||
self.assertTrue(os.path.isfile(outfile))
|
||||
self.assertGreater(os.path.getsize(outfile), 0)
|
||||
|
||||
def test_monochrome(self):
|
||||
# Arrange
|
||||
mode = "1"
|
||||
|
||||
# Act / Assert
|
||||
self.helper_save_as_pdf(mode)
|
||||
|
||||
def test_greyscale(self):
|
||||
# Arrange
|
||||
mode = "L"
|
||||
|
||||
# Act / Assert
|
||||
self.helper_save_as_pdf(mode)
|
||||
|
||||
def test_rgb(self):
|
||||
# Arrange
|
||||
mode = "RGB"
|
||||
|
||||
# Act / Assert
|
||||
self.helper_save_as_pdf(mode)
|
||||
|
||||
def test_p_mode(self):
|
||||
# Arrange
|
||||
mode = "P"
|
||||
|
||||
# Act / Assert
|
||||
self.helper_save_as_pdf(mode)
|
||||
|
||||
def test_cmyk_mode(self):
|
||||
# Arrange
|
||||
mode = "CMYK"
|
||||
|
||||
# Act / Assert
|
||||
self.helper_save_as_pdf(mode)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
|
@ -1,4 +1,6 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
from PIL import Image
|
||||
from PIL import PngImagePlugin
|
||||
|
@ -6,9 +8,6 @@ import zlib
|
|||
|
||||
codecs = dir(Image.core)
|
||||
|
||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
||||
skip("zip/deflate support not available")
|
||||
|
||||
# sample png stream
|
||||
|
||||
file = "Images/lena.png"
|
||||
|
@ -18,6 +17,7 @@ data = open(file, "rb").read()
|
|||
|
||||
MAGIC = PngImagePlugin._MAGIC
|
||||
|
||||
|
||||
def chunk(cid, *data):
|
||||
file = BytesIO()
|
||||
PngImagePlugin.putchunk(*(file, cid) + data)
|
||||
|
@ -32,31 +32,39 @@ IEND = chunk(b"IEND")
|
|||
HEAD = MAGIC + IHDR
|
||||
TAIL = IDAT + IEND
|
||||
|
||||
|
||||
def load(data):
|
||||
return Image.open(BytesIO(data))
|
||||
|
||||
|
||||
def roundtrip(im, **options):
|
||||
out = BytesIO()
|
||||
im.save(out, "PNG", **options)
|
||||
out.seek(0)
|
||||
return Image.open(out)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def test_sanity():
|
||||
class TestFilePng(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
||||
self.skipTest("zip/deflate support not available")
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
# internal version number
|
||||
assert_match(Image.core.zlib_version, "\d+\.\d+\.\d+(\.\d+)?$")
|
||||
self.assertRegexpMatches(
|
||||
Image.core.zlib_version, "\d+\.\d+\.\d+(\.\d+)?$")
|
||||
|
||||
file = tempfile("temp.png")
|
||||
file = self.tempfile("temp.png")
|
||||
|
||||
lena("RGB").save(file)
|
||||
|
||||
im = Image.open(file)
|
||||
im.load()
|
||||
assert_equal(im.mode, "RGB")
|
||||
assert_equal(im.size, (128, 128))
|
||||
assert_equal(im.format, "PNG")
|
||||
self.assertEqual(im.mode, "RGB")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "PNG")
|
||||
|
||||
lena("1").save(file)
|
||||
im = Image.open(file)
|
||||
|
@ -73,145 +81,145 @@ def test_sanity():
|
|||
lena("I").save(file)
|
||||
im = Image.open(file)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def test_broken():
|
||||
def test_broken(self):
|
||||
# Check reading of totally broken files. In this case, the test
|
||||
# file was checked into Subversion as a text file.
|
||||
|
||||
file = "Tests/images/broken.png"
|
||||
assert_exception(IOError, lambda: Image.open(file))
|
||||
self.assertRaises(IOError, lambda: Image.open(file))
|
||||
|
||||
def test_bad_text():
|
||||
def test_bad_text(self):
|
||||
# Make sure PIL can read malformed tEXt chunks (@PIL152)
|
||||
|
||||
im = load(HEAD + chunk(b'tEXt') + TAIL)
|
||||
assert_equal(im.info, {})
|
||||
self.assertEqual(im.info, {})
|
||||
|
||||
im = load(HEAD + chunk(b'tEXt', b'spam') + TAIL)
|
||||
assert_equal(im.info, {'spam': ''})
|
||||
self.assertEqual(im.info, {'spam': ''})
|
||||
|
||||
im = load(HEAD + chunk(b'tEXt', b'spam\0') + TAIL)
|
||||
assert_equal(im.info, {'spam': ''})
|
||||
self.assertEqual(im.info, {'spam': ''})
|
||||
|
||||
im = load(HEAD + chunk(b'tEXt', b'spam\0egg') + TAIL)
|
||||
assert_equal(im.info, {'spam': 'egg'})
|
||||
self.assertEqual(im.info, {'spam': 'egg'})
|
||||
|
||||
im = load(HEAD + chunk(b'tEXt', b'spam\0egg\0') + TAIL)
|
||||
assert_equal(im.info, {'spam': 'egg\x00'})
|
||||
self.assertEqual(im.info, {'spam': 'egg\x00'})
|
||||
|
||||
def test_bad_ztxt():
|
||||
# Test reading malformed zTXt chunks (python-imaging/Pillow#318)
|
||||
def test_bad_ztxt(self):
|
||||
# Test reading malformed zTXt chunks (python-pillow/Pillow#318)
|
||||
|
||||
im = load(HEAD + chunk(b'zTXt') + TAIL)
|
||||
assert_equal(im.info, {})
|
||||
self.assertEqual(im.info, {})
|
||||
|
||||
im = load(HEAD + chunk(b'zTXt', b'spam') + TAIL)
|
||||
assert_equal(im.info, {'spam': ''})
|
||||
self.assertEqual(im.info, {'spam': ''})
|
||||
|
||||
im = load(HEAD + chunk(b'zTXt', b'spam\0') + TAIL)
|
||||
assert_equal(im.info, {'spam': ''})
|
||||
self.assertEqual(im.info, {'spam': ''})
|
||||
|
||||
im = load(HEAD + chunk(b'zTXt', b'spam\0\0') + TAIL)
|
||||
assert_equal(im.info, {'spam': ''})
|
||||
self.assertEqual(im.info, {'spam': ''})
|
||||
|
||||
im = load(HEAD + chunk(b'zTXt', b'spam\0\0' + zlib.compress(b'egg')[:1]) + TAIL)
|
||||
assert_equal(im.info, {'spam': ''})
|
||||
im = load(HEAD + chunk(
|
||||
b'zTXt', b'spam\0\0' + zlib.compress(b'egg')[:1]) + TAIL)
|
||||
self.assertEqual(im.info, {'spam': ''})
|
||||
|
||||
im = load(HEAD + chunk(b'zTXt', b'spam\0\0' + zlib.compress(b'egg')) + TAIL)
|
||||
assert_equal(im.info, {'spam': 'egg'})
|
||||
im = load(
|
||||
HEAD + chunk(b'zTXt', b'spam\0\0' + zlib.compress(b'egg')) + TAIL)
|
||||
self.assertEqual(im.info, {'spam': 'egg'})
|
||||
|
||||
def test_interlace():
|
||||
def test_interlace(self):
|
||||
|
||||
file = "Tests/images/pil123p.png"
|
||||
im = Image.open(file)
|
||||
|
||||
assert_image(im, "P", (162, 150))
|
||||
assert_true(im.info.get("interlace"))
|
||||
self.assert_image(im, "P", (162, 150))
|
||||
self.assertTrue(im.info.get("interlace"))
|
||||
|
||||
assert_no_exception(lambda: im.load())
|
||||
im.load()
|
||||
|
||||
file = "Tests/images/pil123rgba.png"
|
||||
im = Image.open(file)
|
||||
|
||||
assert_image(im, "RGBA", (162, 150))
|
||||
assert_true(im.info.get("interlace"))
|
||||
self.assert_image(im, "RGBA", (162, 150))
|
||||
self.assertTrue(im.info.get("interlace"))
|
||||
|
||||
assert_no_exception(lambda: im.load())
|
||||
im.load()
|
||||
|
||||
def test_load_transparent_p():
|
||||
def test_load_transparent_p(self):
|
||||
file = "Tests/images/pil123p.png"
|
||||
im = Image.open(file)
|
||||
|
||||
assert_image(im, "P", (162, 150))
|
||||
self.assert_image(im, "P", (162, 150))
|
||||
im = im.convert("RGBA")
|
||||
assert_image(im, "RGBA", (162, 150))
|
||||
self.assert_image(im, "RGBA", (162, 150))
|
||||
|
||||
# image has 124 uniqe qlpha values
|
||||
assert_equal(len(im.split()[3].getcolors()), 124)
|
||||
self.assertEqual(len(im.split()[3].getcolors()), 124)
|
||||
|
||||
def test_load_transparent_rgb():
|
||||
def test_load_transparent_rgb(self):
|
||||
file = "Tests/images/rgb_trns.png"
|
||||
im = Image.open(file)
|
||||
|
||||
assert_image(im, "RGB", (64, 64))
|
||||
self.assert_image(im, "RGB", (64, 64))
|
||||
im = im.convert("RGBA")
|
||||
assert_image(im, "RGBA", (64, 64))
|
||||
self.assert_image(im, "RGBA", (64, 64))
|
||||
|
||||
# image has 876 transparent pixels
|
||||
assert_equal(im.split()[3].getcolors()[0][0], 876)
|
||||
self.assertEqual(im.split()[3].getcolors()[0][0], 876)
|
||||
|
||||
def test_save_p_transparent_palette():
|
||||
def test_save_p_transparent_palette(self):
|
||||
in_file = "Tests/images/pil123p.png"
|
||||
im = Image.open(in_file)
|
||||
|
||||
file = tempfile("temp.png")
|
||||
assert_no_exception(lambda: im.save(file))
|
||||
file = self.tempfile("temp.png")
|
||||
im.save(file)
|
||||
|
||||
def test_save_p_single_transparency():
|
||||
def test_save_p_single_transparency(self):
|
||||
in_file = "Tests/images/p_trns_single.png"
|
||||
im = Image.open(in_file)
|
||||
|
||||
file = tempfile("temp.png")
|
||||
assert_no_exception(lambda: im.save(file))
|
||||
file = self.tempfile("temp.png")
|
||||
im.save(file)
|
||||
|
||||
def test_save_l_transparency():
|
||||
def test_save_l_transparency(self):
|
||||
in_file = "Tests/images/l_trns.png"
|
||||
im = Image.open(in_file)
|
||||
|
||||
file = tempfile("temp.png")
|
||||
assert_no_exception(lambda: im.save(file))
|
||||
file = self.tempfile("temp.png")
|
||||
im.save(file)
|
||||
|
||||
# There are 559 transparent pixels.
|
||||
im = im.convert('RGBA')
|
||||
assert_equal(im.split()[3].getcolors()[0][0], 559)
|
||||
self.assertEqual(im.split()[3].getcolors()[0][0], 559)
|
||||
|
||||
def test_save_rgb_single_transparency():
|
||||
def test_save_rgb_single_transparency(self):
|
||||
in_file = "Tests/images/caption_6_33_22.png"
|
||||
im = Image.open(in_file)
|
||||
|
||||
file = tempfile("temp.png")
|
||||
assert_no_exception(lambda: im.save(file))
|
||||
file = self.tempfile("temp.png")
|
||||
im.save(file)
|
||||
|
||||
def test_load_verify():
|
||||
def test_load_verify(self):
|
||||
# Check open/load/verify exception (@PIL150)
|
||||
|
||||
im = Image.open("Images/lena.png")
|
||||
assert_no_exception(lambda: im.verify())
|
||||
im.verify()
|
||||
|
||||
im = Image.open("Images/lena.png")
|
||||
im.load()
|
||||
assert_exception(RuntimeError, lambda: im.verify())
|
||||
self.assertRaises(RuntimeError, lambda: im.verify())
|
||||
|
||||
def test_roundtrip_dpi():
|
||||
def test_roundtrip_dpi(self):
|
||||
# Check dpi roundtripping
|
||||
|
||||
im = Image.open(file)
|
||||
|
||||
im = roundtrip(im, dpi=(100, 100))
|
||||
assert_equal(im.info["dpi"], (100, 100))
|
||||
self.assertEqual(im.info["dpi"], (100, 100))
|
||||
|
||||
def test_roundtrip_text():
|
||||
def test_roundtrip_text(self):
|
||||
# Check text roundtripping
|
||||
|
||||
im = Image.open(file)
|
||||
|
@ -221,10 +229,10 @@ def test_roundtrip_text():
|
|||
info.add_text("ZIP", "VALUE", 1)
|
||||
|
||||
im = roundtrip(im, pnginfo=info)
|
||||
assert_equal(im.info, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
|
||||
assert_equal(im.text, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
|
||||
self.assertEqual(im.info, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
|
||||
self.assertEqual(im.text, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
|
||||
|
||||
def test_scary():
|
||||
def test_scary(self):
|
||||
# Check reading of evil PNG file. For information, see:
|
||||
# http://scary.beasts.org/security/CESA-2004-001.txt
|
||||
# The first byte is removed from pngtest_bad.png
|
||||
|
@ -234,47 +242,46 @@ def test_scary():
|
|||
data = b'\x89' + fd.read()
|
||||
|
||||
pngfile = BytesIO(data)
|
||||
assert_exception(IOError, lambda: Image.open(pngfile))
|
||||
self.assertRaises(IOError, lambda: Image.open(pngfile))
|
||||
|
||||
def test_trns_rgb():
|
||||
def test_trns_rgb(self):
|
||||
# Check writing and reading of tRNS chunks for RGB images.
|
||||
# Independent file sample provided by Sebastian Spaeth.
|
||||
|
||||
file = "Tests/images/caption_6_33_22.png"
|
||||
im = Image.open(file)
|
||||
assert_equal(im.info["transparency"], (248, 248, 248))
|
||||
self.assertEqual(im.info["transparency"], (248, 248, 248))
|
||||
|
||||
# check saving transparency by default
|
||||
im = roundtrip(im)
|
||||
assert_equal(im.info["transparency"], (248, 248, 248))
|
||||
self.assertEqual(im.info["transparency"], (248, 248, 248))
|
||||
|
||||
im = roundtrip(im, transparency=(0, 1, 2))
|
||||
assert_equal(im.info["transparency"], (0, 1, 2))
|
||||
self.assertEqual(im.info["transparency"], (0, 1, 2))
|
||||
|
||||
def test_trns_p():
|
||||
def test_trns_p(self):
|
||||
# Check writing a transparency of 0, issue #528
|
||||
im = lena('P')
|
||||
im.info['transparency'] = 0
|
||||
|
||||
f = tempfile("temp.png")
|
||||
f = self.tempfile("temp.png")
|
||||
im.save(f)
|
||||
|
||||
im2 = Image.open(f)
|
||||
assert_true('transparency' in im2.info)
|
||||
self.assertIn('transparency', im2.info)
|
||||
|
||||
assert_image_equal(im2.convert('RGBA'), im.convert('RGBA'))
|
||||
self.assert_image_equal(im2.convert('RGBA'), im.convert('RGBA'))
|
||||
|
||||
|
||||
def test_save_icc_profile_none():
|
||||
def test_save_icc_profile_none(self):
|
||||
# check saving files with an ICC profile set to None (omit profile)
|
||||
in_file = "Tests/images/icc_profile_none.png"
|
||||
im = Image.open(in_file)
|
||||
assert_equal(im.info['icc_profile'], None)
|
||||
self.assertEqual(im.info['icc_profile'], None)
|
||||
|
||||
im = roundtrip(im)
|
||||
assert_false('icc_profile' in im.info)
|
||||
self.assertNotIn('icc_profile', im.info)
|
||||
|
||||
def test_roundtrip_icc_profile():
|
||||
def test_roundtrip_icc_profile(self):
|
||||
# check that we can roundtrip the icc profile
|
||||
im = lena('RGB')
|
||||
|
||||
|
@ -283,5 +290,10 @@ def test_roundtrip_icc_profile():
|
|||
|
||||
im.info['icc_profile'] = expected_icc
|
||||
im = roundtrip(im)
|
||||
assert_equal(im.info['icc_profile'], expected_icc)
|
||||
self.assertEqual(im.info['icc_profile'], expected_icc)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
@ -6,31 +6,37 @@ from PIL import Image
|
|||
file = "Images/lena.ppm"
|
||||
data = open(file, "rb").read()
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestFilePpm(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
im = Image.open(file)
|
||||
im.load()
|
||||
assert_equal(im.mode, "RGB")
|
||||
assert_equal(im.size, (128, 128))
|
||||
assert_equal(im.format, "PPM")
|
||||
self.assertEqual(im.mode, "RGB")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "PPM")
|
||||
|
||||
def test_16bit_pgm():
|
||||
def test_16bit_pgm(self):
|
||||
im = Image.open('Tests/images/16_bit_binary.pgm')
|
||||
im.load()
|
||||
assert_equal(im.mode, 'I')
|
||||
assert_equal(im.size, (20,100))
|
||||
self.assertEqual(im.mode, 'I')
|
||||
self.assertEqual(im.size, (20, 100))
|
||||
|
||||
tgt = Image.open('Tests/images/16_bit_binary_pgm.png')
|
||||
assert_image_equal(im, tgt)
|
||||
self.assert_image_equal(im, tgt)
|
||||
|
||||
|
||||
def test_16bit_pgm_write():
|
||||
def test_16bit_pgm_write(self):
|
||||
im = Image.open('Tests/images/16_bit_binary.pgm')
|
||||
im.load()
|
||||
|
||||
f = tempfile('temp.pgm')
|
||||
assert_no_exception(lambda: im.save(f, 'PPM'))
|
||||
f = self.tempfile('temp.pgm')
|
||||
im.save(f, 'PPM')
|
||||
|
||||
reloaded = Image.open(f)
|
||||
assert_image_equal(im, reloaded)
|
||||
self.assert_image_equal(im, reloaded)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
@ -6,9 +6,18 @@ from PIL import Image
|
|||
file = "Images/lena.psd"
|
||||
data = open(file, "rb").read()
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImagePsd(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
im = Image.open(file)
|
||||
im.load()
|
||||
assert_equal(im.mode, "RGB")
|
||||
assert_equal(im.size, (128, 128))
|
||||
assert_equal(im.format, "PSD")
|
||||
self.assertEqual(im.mode, "RGB")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "PSD")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
39
Tests/test_file_spider.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
from PIL import SpiderImagePlugin
|
||||
|
||||
test_file = "Tests/images/lena.spider"
|
||||
|
||||
|
||||
class TestImageSpider(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
im = Image.open(test_file)
|
||||
im.load()
|
||||
self.assertEqual(im.mode, "F")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "SPIDER")
|
||||
|
||||
def test_save(self):
|
||||
# Arrange
|
||||
temp = self.tempfile('temp.spider')
|
||||
im = lena()
|
||||
|
||||
# Act
|
||||
im.save(temp, "SPIDER")
|
||||
|
||||
# Assert
|
||||
im2 = Image.open(temp)
|
||||
self.assertEqual(im2.mode, "F")
|
||||
self.assertEqual(im2.size, (128, 128))
|
||||
self.assertEqual(im2.format, "SPIDER")
|
||||
|
||||
def test_isSpiderImage(self):
|
||||
self.assertTrue(SpiderImagePlugin.isSpiderImage(test_file))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
|
@ -1,28 +1,38 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image, TarIO
|
||||
|
||||
codecs = dir(Image.core)
|
||||
if "zip_decoder" not in codecs and "jpeg_decoder" not in codecs:
|
||||
skip("neither jpeg nor zip support not available")
|
||||
|
||||
# sample ppm stream
|
||||
tarfile = "Images/lena.tar"
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestFileTar(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if "zip_decoder" not in codecs and "jpeg_decoder" not in codecs:
|
||||
self.skipTest("neither jpeg nor zip support not available")
|
||||
|
||||
def test_sanity(self):
|
||||
if "zip_decoder" in codecs:
|
||||
tar = TarIO.TarIO(tarfile, 'lena.png')
|
||||
im = Image.open(tar)
|
||||
im.load()
|
||||
assert_equal(im.mode, "RGB")
|
||||
assert_equal(im.size, (128, 128))
|
||||
assert_equal(im.format, "PNG")
|
||||
self.assertEqual(im.mode, "RGB")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "PNG")
|
||||
|
||||
if "jpeg_decoder" in codecs:
|
||||
tar = TarIO.TarIO(tarfile, 'lena.jpg')
|
||||
im = Image.open(tar)
|
||||
im.load()
|
||||
assert_equal(im.mode, "RGB")
|
||||
assert_equal(im.size, (128, 128))
|
||||
assert_equal(im.format, "JPEG")
|
||||
self.assertEqual(im.mode, "RGB")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "JPEG")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena, py3
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
|
||||
file = tempfile("temp.tif")
|
||||
class TestFileTiff(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
file = self.tempfile("temp.tif")
|
||||
|
||||
lena("RGB").save(file)
|
||||
|
||||
im = Image.open(file)
|
||||
im.load()
|
||||
assert_equal(im.mode, "RGB")
|
||||
assert_equal(im.size, (128, 128))
|
||||
assert_equal(im.format, "TIFF")
|
||||
self.assertEqual(im.mode, "RGB")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "TIFF")
|
||||
|
||||
lena("1").save(file)
|
||||
im = Image.open(file)
|
||||
|
@ -29,38 +32,39 @@ def test_sanity():
|
|||
lena("I").save(file)
|
||||
im = Image.open(file)
|
||||
|
||||
def test_mac_tiff():
|
||||
def test_mac_tiff(self):
|
||||
# Read RGBa images from Mac OS X [@PIL136]
|
||||
|
||||
file = "Tests/images/pil136.tiff"
|
||||
im = Image.open(file)
|
||||
|
||||
assert_equal(im.mode, "RGBA")
|
||||
assert_equal(im.size, (55, 43))
|
||||
assert_equal(im.tile, [('raw', (0, 0, 55, 43), 8, ('RGBa', 0, 1))])
|
||||
assert_no_exception(lambda: 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()
|
||||
|
||||
def test_gimp_tiff():
|
||||
def test_gimp_tiff(self):
|
||||
# Read TIFF JPEG images from GIMP [@PIL168]
|
||||
|
||||
codecs = dir(Image.core)
|
||||
if "jpeg_decoder" not in codecs:
|
||||
skip("jpeg support not available")
|
||||
self.skipTest("jpeg support not available")
|
||||
|
||||
file = "Tests/images/pil168.tif"
|
||||
im = Image.open(file)
|
||||
|
||||
assert_equal(im.mode, "RGB")
|
||||
assert_equal(im.size, (256, 256))
|
||||
assert_equal(im.tile, [
|
||||
self.assertEqual(im.mode, "RGB")
|
||||
self.assertEqual(im.size, (256, 256))
|
||||
self.assertEqual(
|
||||
im.tile, [
|
||||
('jpeg', (0, 0, 256, 64), 8, ('RGB', '')),
|
||||
('jpeg', (0, 64, 256, 128), 1215, ('RGB', '')),
|
||||
('jpeg', (0, 128, 256, 192), 2550, ('RGB', '')),
|
||||
('jpeg', (0, 192, 256, 256), 3890, ('RGB', '')),
|
||||
])
|
||||
assert_no_exception(lambda: im.load())
|
||||
im.load()
|
||||
|
||||
def test_xyres_tiff():
|
||||
def test_xyres_tiff(self):
|
||||
from PIL.TiffImagePlugin import X_RESOLUTION, Y_RESOLUTION
|
||||
file = "Tests/images/pil168.tif"
|
||||
im = Image.open(file)
|
||||
|
@ -70,42 +74,40 @@ def test_xyres_tiff():
|
|||
im.tag.tags[X_RESOLUTION] = (72,)
|
||||
im.tag.tags[Y_RESOLUTION] = (72,)
|
||||
im._setup()
|
||||
assert_equal(im.info['dpi'], (72., 72.))
|
||||
self.assertEqual(im.info['dpi'], (72., 72.))
|
||||
|
||||
|
||||
def test_little_endian():
|
||||
def test_little_endian(self):
|
||||
im = Image.open('Tests/images/16bit.cropped.tif')
|
||||
assert_equal(im.getpixel((0,0)), 480)
|
||||
assert_equal(im.mode, 'I;16')
|
||||
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:
|
||||
assert_equal(b[0], ord(b'\xe0'))
|
||||
assert_equal(b[1], ord(b'\x01'))
|
||||
self.assertEqual(b[0], ord(b'\xe0'))
|
||||
self.assertEqual(b[1], ord(b'\x01'))
|
||||
else:
|
||||
assert_equal(b[0], b'\xe0')
|
||||
assert_equal(b[1], b'\x01')
|
||||
self.assertEqual(b[0], b'\xe0')
|
||||
self.assertEqual(b[1], b'\x01')
|
||||
|
||||
|
||||
def test_big_endian():
|
||||
def test_big_endian(self):
|
||||
im = Image.open('Tests/images/16bit.MM.cropped.tif')
|
||||
assert_equal(im.getpixel((0,0)), 480)
|
||||
assert_equal(im.mode, 'I;16B')
|
||||
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:
|
||||
assert_equal(b[0], ord(b'\x01'))
|
||||
assert_equal(b[1], ord(b'\xe0'))
|
||||
self.assertEqual(b[0], ord(b'\x01'))
|
||||
self.assertEqual(b[1], ord(b'\xe0'))
|
||||
else:
|
||||
assert_equal(b[0], b'\x01')
|
||||
assert_equal(b[1], b'\xe0')
|
||||
self.assertEqual(b[0], b'\x01')
|
||||
self.assertEqual(b[1], b'\xe0')
|
||||
|
||||
|
||||
def test_12bit_rawmode():
|
||||
""" Are we generating the same interpretation of the image as Imagemagick is? """
|
||||
def test_12bit_rawmode(self):
|
||||
""" Are we generating the same interpretation
|
||||
of the image as Imagemagick is? """
|
||||
|
||||
# Image.DEBUG = True
|
||||
im = Image.open('Tests/images/12bit.cropped.tif')
|
||||
|
@ -127,15 +129,20 @@ def test_12bit_rawmode():
|
|||
print (im2.getpixel((0, 1)))
|
||||
print (im2.getpixel((0, 2)))
|
||||
|
||||
assert_image_equal(im, im2)
|
||||
self.assert_image_equal(im, im2)
|
||||
|
||||
def test_32bit_float():
|
||||
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()
|
||||
|
||||
assert_equal(im.getpixel((0,0)), -0.4526388943195343)
|
||||
assert_equal(im.getextrema(), (-3.140936851501465, 3.140684127807617))
|
||||
self.assertEqual(im.getpixel((0, 0)), -0.4526388943195343)
|
||||
self.assertEqual(
|
||||
im.getextrema(), (-3.140936851501465, 3.140684127807617))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image, TiffImagePlugin, TiffTags
|
||||
|
||||
tag_ids = dict(zip(TiffTags.TAGS.values(), TiffTags.TAGS.keys()))
|
||||
|
||||
def test_rt_metadata():
|
||||
|
||||
class TestFileTiffMetadata(PillowTestCase):
|
||||
|
||||
def test_rt_metadata(self):
|
||||
""" Test writing arbitray metadata into the tiff image directory
|
||||
Use case is ImageJ private tags, one numeric, one arbitrary
|
||||
data. https://github.com/python-imaging/Pillow/issues/291
|
||||
data. https://github.com/python-pillow/Pillow/issues/291
|
||||
"""
|
||||
|
||||
img = lena()
|
||||
|
@ -17,16 +21,16 @@ def test_rt_metadata():
|
|||
info[tag_ids['ImageJMetaDataByteCounts']] = len(textdata)
|
||||
info[tag_ids['ImageJMetaData']] = textdata
|
||||
|
||||
f = tempfile("temp.tif")
|
||||
f = self.tempfile("temp.tif")
|
||||
|
||||
img.save(f, tiffinfo=info)
|
||||
|
||||
loaded = Image.open(f)
|
||||
|
||||
assert_equal(loaded.tag[50838], (len(textdata),))
|
||||
assert_equal(loaded.tag[50839], textdata)
|
||||
self.assertEqual(loaded.tag[50838], (len(textdata),))
|
||||
self.assertEqual(loaded.tag[50839], textdata)
|
||||
|
||||
def test_read_metadata():
|
||||
def test_read_metadata(self):
|
||||
img = Image.open('Tests/images/lena_g4.tif')
|
||||
|
||||
known = {'YResolution': ((1207959552, 16777216),),
|
||||
|
@ -48,20 +52,20 @@ def test_read_metadata():
|
|||
'StripOffsets': (8,),
|
||||
'Software': 'ImageMagick 6.5.7-8 2012-08-17 Q16 http://www.imagemagick.org'}
|
||||
|
||||
# assert_equal is equivalent, but less helpful in telling what's wrong.
|
||||
# self.assertEqual is equivalent,
|
||||
# but less helpful in telling what's wrong.
|
||||
named = img.tag.named()
|
||||
for tag, value in named.items():
|
||||
assert_equal(known[tag], value)
|
||||
self.assertEqual(known[tag], value)
|
||||
|
||||
for tag, value in known.items():
|
||||
assert_equal(value, named[tag])
|
||||
self.assertEqual(value, named[tag])
|
||||
|
||||
|
||||
def test_write_metadata():
|
||||
def test_write_metadata(self):
|
||||
""" Test metadata writing through the python code """
|
||||
img = Image.open('Tests/images/lena.tif')
|
||||
|
||||
f = tempfile('temp.tiff')
|
||||
f = self.tempfile('temp.tiff')
|
||||
img.save(f, tiffinfo=img.tag)
|
||||
|
||||
loaded = Image.open(f)
|
||||
|
@ -69,12 +73,21 @@ def test_write_metadata():
|
|||
original = img.tag.named()
|
||||
reloaded = loaded.tag.named()
|
||||
|
||||
ignored = ['StripByteCounts', 'RowsPerStrip', 'PageNumber', 'StripOffsets']
|
||||
ignored = [
|
||||
'StripByteCounts', 'RowsPerStrip', 'PageNumber', 'StripOffsets']
|
||||
|
||||
for tag, value in reloaded.items():
|
||||
if tag not in ignored:
|
||||
assert_equal(original[tag], value, "%s didn't roundtrip" % tag)
|
||||
self.assertEqual(
|
||||
original[tag], value, "%s didn't roundtrip" % tag)
|
||||
|
||||
for tag, value in original.items():
|
||||
if tag not in ignored:
|
||||
assert_equal(value, reloaded[tag], "%s didn't roundtrip" % tag)
|
||||
self.assertEqual(
|
||||
value, reloaded[tag], "%s didn't roundtrip" % tag)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,68 +1,79 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
try:
|
||||
from PIL import _webp
|
||||
except:
|
||||
skip('webp support not installed')
|
||||
# Skip in setUp()
|
||||
pass
|
||||
|
||||
|
||||
def test_version():
|
||||
assert_no_exception(lambda: _webp.WebPDecoderVersion())
|
||||
assert_no_exception(lambda: _webp.WebPDecoderBuggyAlpha())
|
||||
class TestFileWebp(PillowTestCase):
|
||||
|
||||
def test_read_rgb():
|
||||
def setUp(self):
|
||||
try:
|
||||
from PIL import _webp
|
||||
except:
|
||||
self.skipTest('WebP support not installed')
|
||||
|
||||
def test_version(self):
|
||||
_webp.WebPDecoderVersion()
|
||||
_webp.WebPDecoderBuggyAlpha()
|
||||
|
||||
def test_read_rgb(self):
|
||||
|
||||
file_path = "Images/lena.webp"
|
||||
image = Image.open(file_path)
|
||||
|
||||
assert_equal(image.mode, "RGB")
|
||||
assert_equal(image.size, (128, 128))
|
||||
assert_equal(image.format, "WEBP")
|
||||
assert_no_exception(lambda: image.load())
|
||||
assert_no_exception(lambda: image.getdata())
|
||||
self.assertEqual(image.mode, "RGB")
|
||||
self.assertEqual(image.size, (128, 128))
|
||||
self.assertEqual(image.format, "WEBP")
|
||||
image.load()
|
||||
image.getdata()
|
||||
|
||||
# generated with: dwebp -ppm ../../Images/lena.webp -o lena_webp_bits.ppm
|
||||
# generated with:
|
||||
# dwebp -ppm ../../Images/lena.webp -o lena_webp_bits.ppm
|
||||
target = Image.open('Tests/images/lena_webp_bits.ppm')
|
||||
assert_image_similar(image, target, 20.0)
|
||||
self.assert_image_similar(image, target, 20.0)
|
||||
|
||||
|
||||
def test_write_rgb():
|
||||
def test_write_rgb(self):
|
||||
"""
|
||||
Can we write a RGB mode file to webp without error. Does it have the bits we
|
||||
expect?
|
||||
|
||||
Can we write a RGB mode file to webp without error.
|
||||
Does it have the bits we expect?
|
||||
"""
|
||||
|
||||
temp_file = tempfile("temp.webp")
|
||||
temp_file = self.tempfile("temp.webp")
|
||||
|
||||
lena("RGB").save(temp_file)
|
||||
|
||||
image = Image.open(temp_file)
|
||||
image.load()
|
||||
|
||||
assert_equal(image.mode, "RGB")
|
||||
assert_equal(image.size, (128, 128))
|
||||
assert_equal(image.format, "WEBP")
|
||||
assert_no_exception(lambda: image.load())
|
||||
assert_no_exception(lambda: image.getdata())
|
||||
self.assertEqual(image.mode, "RGB")
|
||||
self.assertEqual(image.size, (128, 128))
|
||||
self.assertEqual(image.format, "WEBP")
|
||||
image.load()
|
||||
image.getdata()
|
||||
|
||||
# If we're using the exact same version of webp, this test should pass.
|
||||
# but it doesn't if the webp is generated on Ubuntu and tested on Fedora.
|
||||
# If we're using the exact same version of WebP, this test should pass.
|
||||
# but it doesn't if the WebP is generated on Ubuntu and tested on
|
||||
# Fedora.
|
||||
|
||||
# generated with: dwebp -ppm temp.webp -o lena_webp_write.ppm
|
||||
# target = Image.open('Tests/images/lena_webp_write.ppm')
|
||||
#assert_image_equal(image, target)
|
||||
# self.assert_image_equal(image, target)
|
||||
|
||||
# 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 included lena images
|
||||
# for webp are showing ~16 on Ubuntu, the jpegs are showing ~18.
|
||||
# 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 included lena images for WebP are showing ~16 on
|
||||
# Ubuntu, the jpegs are showing ~18.
|
||||
target = lena("RGB")
|
||||
assert_image_similar(image, target, 20.0)
|
||||
|
||||
self.assert_image_similar(image, target, 20.0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,82 +1,91 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
try:
|
||||
from PIL import _webp
|
||||
except:
|
||||
skip('webp support not installed')
|
||||
pass
|
||||
# Skip in setUp()
|
||||
|
||||
|
||||
if _webp.WebPDecoderBuggyAlpha():
|
||||
skip("Buggy early version of webp installed, not testing transparency")
|
||||
class TestFileWebpAlpha(PillowTestCase):
|
||||
|
||||
def test_read_rgba():
|
||||
def setUp(self):
|
||||
try:
|
||||
from PIL import _webp
|
||||
except:
|
||||
self.skipTest('WebP support not installed')
|
||||
|
||||
if _webp.WebPDecoderBuggyAlpha(self):
|
||||
self.skipTest("Buggy early version of WebP installed, not testing transparency")
|
||||
|
||||
def test_read_rgba(self):
|
||||
# Generated with `cwebp transparent.png -o transparent.webp`
|
||||
file_path = "Images/transparent.webp"
|
||||
image = Image.open(file_path)
|
||||
|
||||
assert_equal(image.mode, "RGBA")
|
||||
assert_equal(image.size, (200, 150))
|
||||
assert_equal(image.format, "WEBP")
|
||||
assert_no_exception(lambda: image.load())
|
||||
assert_no_exception(lambda: image.getdata())
|
||||
self.assertEqual(image.mode, "RGBA")
|
||||
self.assertEqual(image.size, (200, 150))
|
||||
self.assertEqual(image.format, "WEBP")
|
||||
image.load()
|
||||
image.getdata()
|
||||
|
||||
orig_bytes = image.tobytes()
|
||||
image.tobytes()
|
||||
|
||||
target = Image.open('Images/transparent.png')
|
||||
assert_image_similar(image, target, 20.0)
|
||||
self.assert_image_similar(image, target, 20.0)
|
||||
|
||||
|
||||
def test_write_lossless_rgb():
|
||||
temp_file = tempfile("temp.webp")
|
||||
def test_write_lossless_rgb(self):
|
||||
temp_file = self.tempfile("temp.webp")
|
||||
# temp_file = "temp.webp"
|
||||
|
||||
pil_image = lena('RGBA')
|
||||
|
||||
mask = Image.new("RGBA", (64, 64), (128, 128, 128, 128))
|
||||
pil_image.paste(mask, (0,0), mask) # add some partially transparent bits.
|
||||
# Add some partially transparent bits:
|
||||
pil_image.paste(mask, (0, 0), mask)
|
||||
|
||||
pil_image.save(temp_file, lossless=True)
|
||||
|
||||
image = Image.open(temp_file)
|
||||
image.load()
|
||||
|
||||
assert_equal(image.mode, "RGBA")
|
||||
assert_equal(image.size, pil_image.size)
|
||||
assert_equal(image.format, "WEBP")
|
||||
assert_no_exception(lambda: image.load())
|
||||
assert_no_exception(lambda: 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)
|
||||
|
||||
assert_image_equal(image, pil_image)
|
||||
|
||||
def test_write_rgba():
|
||||
def test_write_rgba(self):
|
||||
"""
|
||||
Can we write a RGBA mode file to webp without error. Does it have the bits we
|
||||
expect?
|
||||
|
||||
Can we write a RGBA mode file to webp without error.
|
||||
Does it have the bits we expect?
|
||||
"""
|
||||
|
||||
temp_file = tempfile("temp.webp")
|
||||
temp_file = self.tempfile("temp.webp")
|
||||
|
||||
pil_image = Image.new("RGBA", (10, 10), (255, 0, 0, 20))
|
||||
pil_image.save(temp_file)
|
||||
|
||||
if _webp.WebPDecoderBuggyAlpha():
|
||||
if _webp.WebPDecoderBuggyAlpha(self):
|
||||
return
|
||||
|
||||
image = Image.open(temp_file)
|
||||
image.load()
|
||||
|
||||
assert_equal(image.mode, "RGBA")
|
||||
assert_equal(image.size, (10, 10))
|
||||
assert_equal(image.format, "WEBP")
|
||||
assert_no_exception(image.load)
|
||||
assert_no_exception(image.getdata)
|
||||
|
||||
assert_image_similar(image, pil_image, 1.0)
|
||||
self.assertEqual(image.mode, "RGBA")
|
||||
self.assertEqual(image.size, (10, 10))
|
||||
self.assertEqual(image.format, "WEBP")
|
||||
image.load
|
||||
image.getdata
|
||||
|
||||
self.assert_image_similar(image, pil_image, 1.0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,33 +1,43 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
try:
|
||||
from PIL import _webp
|
||||
except:
|
||||
skip('webp support not installed')
|
||||
pass
|
||||
# Skip in setUp()
|
||||
|
||||
|
||||
class TestFileWebpLossless(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
try:
|
||||
from PIL import _webp
|
||||
except:
|
||||
self.skipTest('WebP support not installed')
|
||||
|
||||
if (_webp.WebPDecoderVersion() < 0x0200):
|
||||
skip('lossless not included')
|
||||
self.skipTest('lossless not included')
|
||||
|
||||
def test_write_lossless_rgb():
|
||||
temp_file = tempfile("temp.webp")
|
||||
def test_write_lossless_rgb(self):
|
||||
temp_file = self.tempfile("temp.webp")
|
||||
|
||||
lena("RGB").save(temp_file, lossless=True)
|
||||
|
||||
image = Image.open(temp_file)
|
||||
image.load()
|
||||
|
||||
assert_equal(image.mode, "RGB")
|
||||
assert_equal(image.size, (128, 128))
|
||||
assert_equal(image.format, "WEBP")
|
||||
assert_no_exception(lambda: image.load())
|
||||
assert_no_exception(lambda: image.getdata())
|
||||
|
||||
|
||||
assert_image_equal(image, lena("RGB"))
|
||||
self.assertEqual(image.mode, "RGB")
|
||||
self.assertEqual(image.size, (128, 128))
|
||||
self.assertEqual(image.format, "WEBP")
|
||||
image.load()
|
||||
image.getdata()
|
||||
|
||||
self.assert_image_equal(image, lena("RGB"))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,37 +1,40 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
class TestFileWebpMetadata(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
try:
|
||||
from PIL import _webp
|
||||
if not _webp.HAVE_WEBPMUX:
|
||||
skip('webpmux support not installed')
|
||||
self.skipTest('webpmux support not installed')
|
||||
except:
|
||||
skip('webp support not installed')
|
||||
self.skipTest('WebP support not installed')
|
||||
|
||||
|
||||
|
||||
def test_read_exif_metadata():
|
||||
def test_read_exif_metadata(self):
|
||||
|
||||
file_path = "Images/flower.webp"
|
||||
image = Image.open(file_path)
|
||||
|
||||
assert_equal(image.format, "WEBP")
|
||||
self.assertEqual(image.format, "WEBP")
|
||||
exif_data = image.info.get("exif", None)
|
||||
assert_true(exif_data)
|
||||
self.assertTrue(exif_data)
|
||||
|
||||
exif = image._getexif()
|
||||
|
||||
# camera make
|
||||
assert_equal(exif[271], "Canon")
|
||||
self.assertEqual(exif[271], "Canon")
|
||||
|
||||
jpeg_image = Image.open('Tests/images/flower.jpg')
|
||||
expected_exif = jpeg_image.info['exif']
|
||||
|
||||
assert_equal(exif_data, expected_exif)
|
||||
self.assertEqual(exif_data, expected_exif)
|
||||
|
||||
def test_write_exif_metadata(self):
|
||||
from io import BytesIO
|
||||
|
||||
def test_write_exif_metadata():
|
||||
file_path = "Tests/images/flower.jpg"
|
||||
image = Image.open(file_path)
|
||||
expected_exif = image.info['exif']
|
||||
|
@ -44,28 +47,29 @@ def test_write_exif_metadata():
|
|||
webp_image = Image.open(buffer)
|
||||
|
||||
webp_exif = webp_image.info.get('exif', None)
|
||||
assert_true(webp_exif)
|
||||
self.assertTrue(webp_exif)
|
||||
if webp_exif:
|
||||
assert_equal(webp_exif, expected_exif, "Webp Exif didn't match")
|
||||
self.assertEqual(
|
||||
webp_exif, expected_exif, "WebP EXIF didn't match")
|
||||
|
||||
|
||||
def test_read_icc_profile():
|
||||
def test_read_icc_profile(self):
|
||||
|
||||
file_path = "Images/flower2.webp"
|
||||
image = Image.open(file_path)
|
||||
|
||||
assert_equal(image.format, "WEBP")
|
||||
assert_true(image.info.get("icc_profile", None))
|
||||
self.assertEqual(image.format, "WEBP")
|
||||
self.assertTrue(image.info.get("icc_profile", None))
|
||||
|
||||
icc = image.info['icc_profile']
|
||||
|
||||
jpeg_image = Image.open('Tests/images/flower2.jpg')
|
||||
expected_icc = jpeg_image.info['icc_profile']
|
||||
|
||||
assert_equal(icc, expected_icc)
|
||||
self.assertEqual(icc, expected_icc)
|
||||
|
||||
def test_write_icc_metadata(self):
|
||||
from io import BytesIO
|
||||
|
||||
def test_write_icc_metadata():
|
||||
file_path = "Tests/images/flower2.jpg"
|
||||
image = Image.open(file_path)
|
||||
expected_icc_profile = image.info['icc_profile']
|
||||
|
@ -79,15 +83,18 @@ def test_write_icc_metadata():
|
|||
|
||||
webp_icc_profile = webp_image.info.get('icc_profile', None)
|
||||
|
||||
assert_true(webp_icc_profile)
|
||||
self.assertTrue(webp_icc_profile)
|
||||
if webp_icc_profile:
|
||||
assert_equal(webp_icc_profile, expected_icc_profile, "Webp ICC didn't match")
|
||||
self.assertEqual(
|
||||
webp_icc_profile, expected_icc_profile,
|
||||
"Webp ICC didn't match")
|
||||
|
||||
def test_read_no_exif(self):
|
||||
from io import BytesIO
|
||||
|
||||
def test_read_no_exif():
|
||||
file_path = "Tests/images/flower.jpg"
|
||||
image = Image.open(file_path)
|
||||
expected_exif = image.info['exif']
|
||||
image.info['exif']
|
||||
|
||||
buffer = BytesIO()
|
||||
|
||||
|
@ -96,6 +103,10 @@ def test_read_no_exif():
|
|||
buffer.seek(0)
|
||||
webp_image = Image.open(buffer)
|
||||
|
||||
assert_false(webp_image._getexif())
|
||||
self.assertFalse(webp_image._getexif())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
@ -25,10 +25,20 @@ static char basic_bits[] = {
|
|||
};
|
||||
"""
|
||||
|
||||
def test_pil151():
|
||||
|
||||
class TestFileXbm(PillowTestCase):
|
||||
|
||||
def test_pil151(self):
|
||||
from io import BytesIO
|
||||
|
||||
im = Image.open(BytesIO(PIL151))
|
||||
|
||||
assert_no_exception(lambda: im.load())
|
||||
assert_equal(im.mode, '1')
|
||||
assert_equal(im.size, (32, 32))
|
||||
im.load()
|
||||
self.assertEqual(im.mode, '1')
|
||||
self.assertEqual(im.size, (32, 32))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
@ -6,9 +6,18 @@ from PIL import Image
|
|||
file = "Images/lena.xpm"
|
||||
data = open(file, "rb").read()
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestFileXpm(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
im = Image.open(file)
|
||||
im.load()
|
||||
assert_equal(im.mode, "P")
|
||||
assert_equal(im.size, (128, 128))
|
||||
assert_equal(im.format, "XPM")
|
||||
self.assertEqual(im.mode, "P")
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.format, "XPM")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image, FontFile, BdfFontFile
|
||||
from PIL import FontFile, BdfFontFile
|
||||
|
||||
filename = "Images/courB08.bdf"
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestFontBdf(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
file = open(filename, "rb")
|
||||
font = BdfFontFile.BdfFontFile(file)
|
||||
|
||||
assert_true(isinstance(font, FontFile.FontFile))
|
||||
assert_equal(len([_f for _f in font.glyph if _f]), 190)
|
||||
self.assertIsInstance(font, FontFile.FontFile)
|
||||
self.assertEqual(len([_f for _f in font.glyph if _f]), 190)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,49 +1,63 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image, FontFile, PcfFontFile
|
||||
from PIL import ImageFont, ImageDraw
|
||||
|
||||
codecs = dir(Image.core)
|
||||
|
||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
||||
skip("zlib support not available")
|
||||
|
||||
fontname = "Tests/fonts/helvO18.pcf"
|
||||
tempname = tempfile("temp.pil", "temp.pbm")
|
||||
|
||||
message = "hello, world"
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestFontPcf(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
||||
self.skipTest("zlib support not available")
|
||||
|
||||
def save_font(self):
|
||||
file = open(fontname, "rb")
|
||||
font = PcfFontFile.PcfFontFile(file)
|
||||
assert_true(isinstance(font, FontFile.FontFile))
|
||||
assert_equal(len([_f for _f in font.glyph if _f]), 192)
|
||||
self.assertIsInstance(font, FontFile.FontFile)
|
||||
self.assertEqual(len([_f for _f in font.glyph if _f]), 192)
|
||||
|
||||
tempname = self.tempfile("temp.pil", "temp.pbm")
|
||||
font.save(tempname)
|
||||
return tempname
|
||||
|
||||
def xtest_draw():
|
||||
def test_sanity(self):
|
||||
self.save_font()
|
||||
|
||||
def xtest_draw(self):
|
||||
|
||||
tempname = self.save_font()
|
||||
font = ImageFont.load(tempname)
|
||||
image = Image.new("L", font.getsize(message), "white")
|
||||
draw = ImageDraw.Draw(image)
|
||||
draw.text((0, 0), message, font=font)
|
||||
# assert_signature(image, "7216c60f988dea43a46bb68321e3c1b03ec62aee")
|
||||
|
||||
def _test_high_characters(message):
|
||||
def _test_high_characters(self, message):
|
||||
|
||||
tempname = self.save_font()
|
||||
font = ImageFont.load(tempname)
|
||||
image = Image.new("L", font.getsize(message), "white")
|
||||
draw = ImageDraw.Draw(image)
|
||||
draw.text((0, 0), message, font=font)
|
||||
|
||||
compare = Image.open('Tests/images/high_ascii_chars.png')
|
||||
assert_image_equal(image, compare)
|
||||
self.assert_image_equal(image, compare)
|
||||
|
||||
def test_high_characters():
|
||||
def test_high_characters(self):
|
||||
message = "".join([chr(i+1) for i in range(140, 232)])
|
||||
_test_high_characters(message)
|
||||
self._test_high_characters(message)
|
||||
# accept bytes instances in Py3.
|
||||
if bytes is not str:
|
||||
_test_high_characters(message.encode('latin1'))
|
||||
self._test_high_characters(message.encode('latin1'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,41 +1,48 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_white():
|
||||
|
||||
class TestFormatLab(PillowTestCase):
|
||||
|
||||
def test_white(self):
|
||||
i = Image.open('Tests/images/lab.tif')
|
||||
|
||||
bits = i.load()
|
||||
i.load()
|
||||
|
||||
assert_equal(i.mode, 'LAB')
|
||||
self.assertEqual(i.mode, 'LAB')
|
||||
|
||||
assert_equal(i.getbands(), ('L','A', 'B'))
|
||||
self.assertEqual(i.getbands(), ('L', 'A', 'B'))
|
||||
|
||||
k = i.getpixel((0, 0))
|
||||
assert_equal(k, (255,128,128))
|
||||
self.assertEqual(k, (255, 128, 128))
|
||||
|
||||
L = i.getdata(0)
|
||||
a = i.getdata(1)
|
||||
b = i.getdata(2)
|
||||
|
||||
assert_equal(list(L), [255]*100)
|
||||
assert_equal(list(a), [128]*100)
|
||||
assert_equal(list(b), [128]*100)
|
||||
self.assertEqual(list(L), [255]*100)
|
||||
self.assertEqual(list(a), [128]*100)
|
||||
self.assertEqual(list(b), [128]*100)
|
||||
|
||||
|
||||
def test_green():
|
||||
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))
|
||||
assert_equal(k, (128,28,128))
|
||||
self.assertEqual(k, (128, 28, 128))
|
||||
|
||||
|
||||
def test_red():
|
||||
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))
|
||||
assert_equal(k, (128,228,128))
|
||||
self.assertEqual(k, (128, 228, 128))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,39 +1,51 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImage(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
im = Image.new("L", (100, 100))
|
||||
assert_equal(repr(im)[:45], "<PIL.Image.Image image mode=L size=100x100 at")
|
||||
assert_equal(im.mode, "L")
|
||||
assert_equal(im.size, (100, 100))
|
||||
self.assertEqual(
|
||||
repr(im)[:45], "<PIL.Image.Image image mode=L size=100x100 at")
|
||||
self.assertEqual(im.mode, "L")
|
||||
self.assertEqual(im.size, (100, 100))
|
||||
|
||||
im = Image.new("RGB", (100, 100))
|
||||
assert_equal(repr(im)[:45], "<PIL.Image.Image image mode=RGB size=100x100 ")
|
||||
assert_equal(im.mode, "RGB")
|
||||
assert_equal(im.size, (100, 100))
|
||||
self.assertEqual(
|
||||
repr(im)[:45], "<PIL.Image.Image image mode=RGB size=100x100 ")
|
||||
self.assertEqual(im.mode, "RGB")
|
||||
self.assertEqual(im.size, (100, 100))
|
||||
|
||||
im1 = Image.new("L", (100, 100), None)
|
||||
Image.new("L", (100, 100), None)
|
||||
im2 = Image.new("L", (100, 100), 0)
|
||||
im3 = Image.new("L", (100, 100), "black")
|
||||
|
||||
assert_equal(im2.getcolors(), [(10000, 0)])
|
||||
assert_equal(im3.getcolors(), [(10000, 0)])
|
||||
self.assertEqual(im2.getcolors(), [(10000, 0)])
|
||||
self.assertEqual(im3.getcolors(), [(10000, 0)])
|
||||
|
||||
assert_exception(ValueError, lambda: Image.new("X", (100, 100)))
|
||||
# assert_exception(MemoryError, lambda: Image.new("L", (1000000, 1000000)))
|
||||
self.assertRaises(ValueError, lambda: Image.new("X", (100, 100)))
|
||||
# self.assertRaises(
|
||||
# MemoryError, lambda: Image.new("L", (1000000, 1000000)))
|
||||
|
||||
def test_internals():
|
||||
def test_internals(self):
|
||||
|
||||
im = Image.new("L", (100, 100))
|
||||
im.readonly = 1
|
||||
im._copy()
|
||||
assert_false(im.readonly)
|
||||
self.assertFalse(im.readonly)
|
||||
|
||||
im.readonly = 1
|
||||
im.paste(0, (0, 0, 100, 100))
|
||||
assert_false(im.readonly)
|
||||
self.assertFalse(im.readonly)
|
||||
|
||||
file = tempfile("temp.ppm")
|
||||
file = self.tempfile("temp.ppm")
|
||||
im._dump(file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,22 +1,29 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
im = lena().resize((128, 100))
|
||||
|
||||
def test_toarray():
|
||||
|
||||
class TestImageCrop(PillowTestCase):
|
||||
|
||||
def test_toarray(self):
|
||||
def test(mode):
|
||||
ai = im.convert(mode).__array_interface__
|
||||
return ai["shape"], ai["typestr"], len(ai["data"])
|
||||
# assert_equal(test("1"), ((100, 128), '|b1', 1600))
|
||||
assert_equal(test("L"), ((100, 128), '|u1', 12800))
|
||||
assert_equal(test("I"), ((100, 128), Image._ENDIAN + 'i4', 51200)) # FIXME: wrong?
|
||||
assert_equal(test("F"), ((100, 128), Image._ENDIAN + 'f4', 51200)) # FIXME: wrong?
|
||||
assert_equal(test("RGB"), ((100, 128, 3), '|u1', 38400))
|
||||
assert_equal(test("RGBA"), ((100, 128, 4), '|u1', 51200))
|
||||
assert_equal(test("RGBX"), ((100, 128, 4), '|u1', 51200))
|
||||
# self.assertEqual(test("1"), ((100, 128), '|b1', 1600))
|
||||
self.assertEqual(test("L"), ((100, 128), '|u1', 12800))
|
||||
|
||||
def test_fromarray():
|
||||
# FIXME: wrong?
|
||||
self.assertEqual(test("I"), ((100, 128), Image._ENDIAN + 'i4', 51200))
|
||||
# FIXME: wrong?
|
||||
self.assertEqual(test("F"), ((100, 128), Image._ENDIAN + 'f4', 51200))
|
||||
|
||||
self.assertEqual(test("RGB"), ((100, 128, 3), '|u1', 38400))
|
||||
self.assertEqual(test("RGBA"), ((100, 128, 4), '|u1', 51200))
|
||||
self.assertEqual(test("RGBX"), ((100, 128, 4), '|u1', 51200))
|
||||
|
||||
def test_fromarray(self):
|
||||
def test(mode):
|
||||
i = im.convert(mode)
|
||||
a = i.__array_interface__
|
||||
|
@ -24,10 +31,16 @@ def test_fromarray():
|
|||
i.__array_interface__ = a # patch in new version of attribute
|
||||
out = Image.fromarray(i)
|
||||
return out.mode, out.size, list(i.getdata()) == list(out.getdata())
|
||||
# assert_equal(test("1"), ("1", (128, 100), True))
|
||||
assert_equal(test("L"), ("L", (128, 100), True))
|
||||
assert_equal(test("I"), ("I", (128, 100), True))
|
||||
assert_equal(test("F"), ("F", (128, 100), True))
|
||||
assert_equal(test("RGB"), ("RGB", (128, 100), True))
|
||||
assert_equal(test("RGBA"), ("RGBA", (128, 100), True))
|
||||
assert_equal(test("RGBX"), ("RGBA", (128, 100), True))
|
||||
# self.assertEqual(test("1"), ("1", (128, 100), True))
|
||||
self.assertEqual(test("L"), ("L", (128, 100), True))
|
||||
self.assertEqual(test("I"), ("I", (128, 100), True))
|
||||
self.assertEqual(test("F"), ("F", (128, 100), True))
|
||||
self.assertEqual(test("RGB"), ("RGB", (128, 100), True))
|
||||
self.assertEqual(test("RGBA"), ("RGBA", (128, 100), True))
|
||||
self.assertEqual(test("RGBX"), ("RGBA", (128, 100), True))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,112 +1,130 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImageConvert(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
def convert(im, mode):
|
||||
out = im.convert(mode)
|
||||
assert_equal(out.mode, mode)
|
||||
assert_equal(out.size, im.size)
|
||||
self.assertEqual(out.mode, mode)
|
||||
self.assertEqual(out.size, im.size)
|
||||
|
||||
modes = "1", "L", "I", "F", "RGB", "RGBA", "RGBX", "CMYK", "YCbCr"
|
||||
|
||||
for mode in modes:
|
||||
im = lena(mode)
|
||||
for mode in modes:
|
||||
yield_test(convert, im, mode)
|
||||
convert(im, mode)
|
||||
|
||||
def test_default():
|
||||
def test_default(self):
|
||||
|
||||
im = lena("P")
|
||||
assert_image(im, "P", im.size)
|
||||
self.assert_image(im, "P", im.size)
|
||||
im = im.convert()
|
||||
assert_image(im, "RGB", im.size)
|
||||
self.assert_image(im, "RGB", im.size)
|
||||
im = im.convert()
|
||||
assert_image(im, "RGB", im.size)
|
||||
self.assert_image(im, "RGB", im.size)
|
||||
|
||||
# ref https://github.com/python-pillow/Pillow/issues/274
|
||||
|
||||
|
||||
# ref https://github.com/python-imaging/Pillow/issues/274
|
||||
|
||||
def _test_float_conversion(im):
|
||||
def _test_float_conversion(self, im):
|
||||
orig = im.getpixel((5, 5))
|
||||
converted = im.convert('F').getpixel((5, 5))
|
||||
assert_equal(orig, converted)
|
||||
self.assertEqual(orig, converted)
|
||||
|
||||
def test_8bit():
|
||||
def test_8bit(self):
|
||||
im = Image.open('Images/lena.jpg')
|
||||
_test_float_conversion(im.convert('L'))
|
||||
self._test_float_conversion(im.convert('L'))
|
||||
|
||||
def test_16bit():
|
||||
def test_16bit(self):
|
||||
im = Image.open('Tests/images/16bit.cropped.tif')
|
||||
_test_float_conversion(im)
|
||||
self._test_float_conversion(im)
|
||||
|
||||
def test_16bit_workaround():
|
||||
def test_16bit_workaround(self):
|
||||
im = Image.open('Tests/images/16bit.cropped.tif')
|
||||
_test_float_conversion(im.convert('I'))
|
||||
self._test_float_conversion(im.convert('I'))
|
||||
|
||||
def test_rgba_p():
|
||||
def test_rgba_p(self):
|
||||
im = lena('RGBA')
|
||||
im.putalpha(lena('L'))
|
||||
|
||||
converted = im.convert('P')
|
||||
comparable = converted.convert('RGBA')
|
||||
|
||||
assert_image_similar(im, comparable, 20)
|
||||
self.assert_image_similar(im, comparable, 20)
|
||||
|
||||
def test_trns_p():
|
||||
def test_trns_p(self):
|
||||
im = lena('P')
|
||||
im.info['transparency'] = 0
|
||||
|
||||
f = tempfile('temp.png')
|
||||
f = self.tempfile('temp.png')
|
||||
|
||||
l = im.convert('L')
|
||||
assert_equal(l.info['transparency'], 0) # undone
|
||||
assert_no_exception(lambda: l.save(f))
|
||||
|
||||
self.assertEqual(l.info['transparency'], 0) # undone
|
||||
l.save(f)
|
||||
|
||||
rgb = im.convert('RGB')
|
||||
assert_equal(rgb.info['transparency'], (0,0,0)) # undone
|
||||
assert_no_exception(lambda: rgb.save(f))
|
||||
self.assertEqual(rgb.info['transparency'], (0, 0, 0)) # undone
|
||||
rgb.save(f)
|
||||
|
||||
def test_trns_l():
|
||||
# ref https://github.com/python-pillow/Pillow/issues/664
|
||||
|
||||
def test_trns_p_rgba(self):
|
||||
# Arrange
|
||||
im = lena('P')
|
||||
im.info['transparency'] = 128
|
||||
|
||||
# Act
|
||||
rgba = im.convert('RGBA')
|
||||
|
||||
# Assert
|
||||
self.assertNotIn('transparency', rgba.info)
|
||||
|
||||
def test_trns_l(self):
|
||||
im = lena('L')
|
||||
im.info['transparency'] = 128
|
||||
|
||||
f = tempfile('temp.png')
|
||||
f = self.tempfile('temp.png')
|
||||
|
||||
rgb = im.convert('RGB')
|
||||
assert_equal(rgb.info['transparency'], (128,128,128)) # undone
|
||||
assert_no_exception(lambda: rgb.save(f))
|
||||
self.assertEqual(rgb.info['transparency'], (128, 128, 128)) # undone
|
||||
rgb.save(f)
|
||||
|
||||
p = im.convert('P')
|
||||
assert_true('transparency' in p.info)
|
||||
assert_no_exception(lambda: p.save(f))
|
||||
self.assertIn('transparency', p.info)
|
||||
p.save(f)
|
||||
|
||||
p = assert_warning(UserWarning,
|
||||
p = self.assert_warning(
|
||||
UserWarning,
|
||||
lambda: im.convert('P', palette=Image.ADAPTIVE))
|
||||
assert_false('transparency' in p.info)
|
||||
assert_no_exception(lambda: p.save(f))
|
||||
self.assertNotIn('transparency', p.info)
|
||||
p.save(f)
|
||||
|
||||
|
||||
def test_trns_RGB():
|
||||
def test_trns_RGB(self):
|
||||
im = lena('RGB')
|
||||
im.info['transparency'] = im.getpixel((0, 0))
|
||||
|
||||
f = tempfile('temp.png')
|
||||
f = self.tempfile('temp.png')
|
||||
|
||||
l = im.convert('L')
|
||||
assert_equal(l.info['transparency'], l.getpixel((0,0))) # undone
|
||||
assert_no_exception(lambda: l.save(f))
|
||||
self.assertEqual(l.info['transparency'], l.getpixel((0, 0))) # undone
|
||||
l.save(f)
|
||||
|
||||
p = im.convert('P')
|
||||
assert_true('transparency' in p.info)
|
||||
assert_no_exception(lambda: p.save(f))
|
||||
self.assertIn('transparency', p.info)
|
||||
p.save(f)
|
||||
|
||||
p = assert_warning(UserWarning,
|
||||
p = self.assert_warning(
|
||||
UserWarning,
|
||||
lambda: im.convert('P', palette=Image.ADAPTIVE))
|
||||
assert_false('transparency' in p.info)
|
||||
assert_no_exception(lambda: p.save(f))
|
||||
self.assertNotIn('transparency', p.info)
|
||||
p.save(f)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_copy():
|
||||
|
||||
class TestImageCopy(PillowTestCase):
|
||||
|
||||
def test_copy(self):
|
||||
def copy(mode):
|
||||
im = lena(mode)
|
||||
out = im.copy()
|
||||
assert_equal(out.mode, mode)
|
||||
assert_equal(out.size, im.size)
|
||||
self.assertEqual(out.mode, mode)
|
||||
self.assertEqual(out.size, im.size)
|
||||
for mode in "1", "P", "L", "RGB", "I", "F":
|
||||
yield_test(copy, mode)
|
||||
copy(mode)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_crop():
|
||||
|
||||
class TestImageCrop(PillowTestCase):
|
||||
|
||||
def test_crop(self):
|
||||
def crop(mode):
|
||||
out = lena(mode).crop((50, 50, 100, 100))
|
||||
assert_equal(out.mode, mode)
|
||||
assert_equal(out.size, (50, 50))
|
||||
self.assertEqual(out.mode, mode)
|
||||
self.assertEqual(out.size, (50, 50))
|
||||
for mode in "1", "P", "L", "RGB", "I", "F":
|
||||
yield_test(crop, mode)
|
||||
crop(mode)
|
||||
|
||||
def test_wide_crop():
|
||||
def test_wide_crop(self):
|
||||
|
||||
def crop(*bbox):
|
||||
i = im.crop(bbox)
|
||||
|
@ -21,32 +24,36 @@ def test_wide_crop():
|
|||
|
||||
im = Image.new("L", (100, 100), 1)
|
||||
|
||||
assert_equal(crop(0, 0, 100, 100), (0, 10000))
|
||||
assert_equal(crop(25, 25, 75, 75), (0, 2500))
|
||||
self.assertEqual(crop(0, 0, 100, 100), (0, 10000))
|
||||
self.assertEqual(crop(25, 25, 75, 75), (0, 2500))
|
||||
|
||||
# sides
|
||||
assert_equal(crop(-25, 0, 25, 50), (1250, 1250))
|
||||
assert_equal(crop(0, -25, 50, 25), (1250, 1250))
|
||||
assert_equal(crop(75, 0, 125, 50), (1250, 1250))
|
||||
assert_equal(crop(0, 75, 50, 125), (1250, 1250))
|
||||
self.assertEqual(crop(-25, 0, 25, 50), (1250, 1250))
|
||||
self.assertEqual(crop(0, -25, 50, 25), (1250, 1250))
|
||||
self.assertEqual(crop(75, 0, 125, 50), (1250, 1250))
|
||||
self.assertEqual(crop(0, 75, 50, 125), (1250, 1250))
|
||||
|
||||
assert_equal(crop(-25, 25, 125, 75), (2500, 5000))
|
||||
assert_equal(crop(25, -25, 75, 125), (2500, 5000))
|
||||
self.assertEqual(crop(-25, 25, 125, 75), (2500, 5000))
|
||||
self.assertEqual(crop(25, -25, 75, 125), (2500, 5000))
|
||||
|
||||
# corners
|
||||
assert_equal(crop(-25, -25, 25, 25), (1875, 625))
|
||||
assert_equal(crop(75, -25, 125, 25), (1875, 625))
|
||||
assert_equal(crop(75, 75, 125, 125), (1875, 625))
|
||||
assert_equal(crop(-25, 75, 25, 125), (1875, 625))
|
||||
self.assertEqual(crop(-25, -25, 25, 25), (1875, 625))
|
||||
self.assertEqual(crop(75, -25, 125, 25), (1875, 625))
|
||||
self.assertEqual(crop(75, 75, 125, 125), (1875, 625))
|
||||
self.assertEqual(crop(-25, 75, 25, 125), (1875, 625))
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def test_negative_crop():
|
||||
def test_negative_crop(self):
|
||||
# Check negative crop size (@PIL171)
|
||||
|
||||
im = Image.new("L", (512, 512))
|
||||
im = im.crop((400, 400, 200, 200))
|
||||
|
||||
assert_equal(im.size, (0, 0))
|
||||
assert_equal(len(im.getdata()), 0)
|
||||
assert_exception(IndexError, lambda: im.getdata()[0])
|
||||
self.assertEqual(im.size, (0, 0))
|
||||
self.assertEqual(len(im.getdata()), 0)
|
||||
self.assertRaises(IndexError, lambda: im.getdata()[0])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,30 +1,39 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, fromstring, tostring
|
||||
|
||||
from PIL import Image
|
||||
|
||||
codecs = dir(Image.core)
|
||||
|
||||
if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs:
|
||||
skip("jpeg support not available")
|
||||
|
||||
filename = "Images/lena.jpg"
|
||||
|
||||
data = tostring(Image.open(filename).resize((512, 512)), "JPEG")
|
||||
|
||||
|
||||
def draft(mode, size):
|
||||
im = fromstring(data)
|
||||
im.draft(mode, size)
|
||||
return im
|
||||
|
||||
def test_size():
|
||||
assert_equal(draft("RGB", (512, 512)).size, (512, 512))
|
||||
assert_equal(draft("RGB", (256, 256)).size, (256, 256))
|
||||
assert_equal(draft("RGB", (128, 128)).size, (128, 128))
|
||||
assert_equal(draft("RGB", (64, 64)).size, (64, 64))
|
||||
assert_equal(draft("RGB", (32, 32)).size, (64, 64))
|
||||
|
||||
def test_mode():
|
||||
assert_equal(draft("1", (512, 512)).mode, "RGB")
|
||||
assert_equal(draft("L", (512, 512)).mode, "L")
|
||||
assert_equal(draft("RGB", (512, 512)).mode, "RGB")
|
||||
assert_equal(draft("YCbCr", (512, 512)).mode, "YCbCr")
|
||||
class TestImageDraft(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if "jpeg_encoder" not in codecs or "jpeg_decoder" not in codecs:
|
||||
self.skipTest("jpeg support not available")
|
||||
|
||||
def test_size(self):
|
||||
self.assertEqual(draft("RGB", (512, 512)).size, (512, 512))
|
||||
self.assertEqual(draft("RGB", (256, 256)).size, (256, 256))
|
||||
self.assertEqual(draft("RGB", (128, 128)).size, (128, 128))
|
||||
self.assertEqual(draft("RGB", (64, 64)).size, (64, 64))
|
||||
self.assertEqual(draft("RGB", (32, 32)).size, (64, 64))
|
||||
|
||||
def test_mode(self):
|
||||
self.assertEqual(draft("1", (512, 512)).mode, "RGB")
|
||||
self.assertEqual(draft("L", (512, 512)).mode, "L")
|
||||
self.assertEqual(draft("RGB", (512, 512)).mode, "RGB")
|
||||
self.assertEqual(draft("YCbCr", (512, 512)).mode, "YCbCr")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
from PIL import ImageFilter
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImageFilter(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
def filter(filter):
|
||||
im = lena("L")
|
||||
out = im.filter(filter)
|
||||
assert_equal(out.mode, im.mode)
|
||||
assert_equal(out.size, im.size)
|
||||
self.assertEqual(out.mode, im.mode)
|
||||
self.assertEqual(out.size, im.size)
|
||||
|
||||
filter(ImageFilter.BLUR)
|
||||
filter(ImageFilter.CONTOUR)
|
||||
|
@ -27,21 +30,21 @@ def test_sanity():
|
|||
filter(ImageFilter.ModeFilter)
|
||||
filter(ImageFilter.Kernel((3, 3), list(range(9))))
|
||||
|
||||
assert_exception(TypeError, lambda: filter("hello"))
|
||||
self.assertRaises(TypeError, lambda: filter("hello"))
|
||||
|
||||
def test_crash():
|
||||
def test_crash(self):
|
||||
|
||||
# crashes on small images
|
||||
im = Image.new("RGB", (1, 1))
|
||||
assert_no_exception(lambda: im.filter(ImageFilter.SMOOTH))
|
||||
im.filter(ImageFilter.SMOOTH)
|
||||
|
||||
im = Image.new("RGB", (2, 2))
|
||||
assert_no_exception(lambda: im.filter(ImageFilter.SMOOTH))
|
||||
im.filter(ImageFilter.SMOOTH)
|
||||
|
||||
im = Image.new("RGB", (3, 3))
|
||||
assert_no_exception(lambda: im.filter(ImageFilter.SMOOTH))
|
||||
im.filter(ImageFilter.SMOOTH)
|
||||
|
||||
def test_modefilter():
|
||||
def test_modefilter(self):
|
||||
|
||||
def modefilter(mode):
|
||||
im = Image.new(mode, (3, 3), None)
|
||||
|
@ -55,12 +58,12 @@ def test_modefilter():
|
|||
mod2 = im.filter(ImageFilter.ModeFilter).getpixel((1, 1))
|
||||
return mod, mod2
|
||||
|
||||
assert_equal(modefilter("1"), (4, 0))
|
||||
assert_equal(modefilter("L"), (4, 0))
|
||||
assert_equal(modefilter("P"), (4, 0))
|
||||
assert_equal(modefilter("RGB"), ((4, 0, 0), (0, 0, 0)))
|
||||
self.assertEqual(modefilter("1"), (4, 0))
|
||||
self.assertEqual(modefilter("L"), (4, 0))
|
||||
self.assertEqual(modefilter("P"), (4, 0))
|
||||
self.assertEqual(modefilter("RGB"), ((4, 0, 0), (0, 0, 0)))
|
||||
|
||||
def test_rankfilter():
|
||||
def test_rankfilter(self):
|
||||
|
||||
def rankfilter(mode):
|
||||
im = Image.new(mode, (3, 3), None)
|
||||
|
@ -74,9 +77,15 @@ def test_rankfilter():
|
|||
max = im.filter(ImageFilter.MaxFilter).getpixel((1, 1))
|
||||
return min, med, max
|
||||
|
||||
assert_equal(rankfilter("1"), (0, 4, 8))
|
||||
assert_equal(rankfilter("L"), (0, 4, 8))
|
||||
assert_exception(ValueError, lambda: rankfilter("P"))
|
||||
assert_equal(rankfilter("RGB"), ((0, 0, 0), (4, 0, 0), (8, 0, 0)))
|
||||
assert_equal(rankfilter("I"), (0, 4, 8))
|
||||
assert_equal(rankfilter("F"), (0.0, 4.0, 8.0))
|
||||
self.assertEqual(rankfilter("1"), (0, 4, 8))
|
||||
self.assertEqual(rankfilter("L"), (0, 4, 8))
|
||||
self.assertRaises(ValueError, lambda: rankfilter("P"))
|
||||
self.assertEqual(rankfilter("RGB"), ((0, 0, 0), (4, 0, 0), (8, 0, 0)))
|
||||
self.assertEqual(rankfilter("I"), (0, 4, 8))
|
||||
self.assertEqual(rankfilter("F"), (0.0, 4.0, 8.0))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImageFromBytes(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
im1 = lena()
|
||||
im2 = Image.frombytes(im1.mode, im1.size, im1.tobytes())
|
||||
|
||||
assert_image_equal(im1, im2)
|
||||
self.assert_image_equal(im1, im2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,15 +1,26 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_getbands():
|
||||
|
||||
assert_equal(Image.new("1", (1, 1)).getbands(), ("1",))
|
||||
assert_equal(Image.new("L", (1, 1)).getbands(), ("L",))
|
||||
assert_equal(Image.new("I", (1, 1)).getbands(), ("I",))
|
||||
assert_equal(Image.new("F", (1, 1)).getbands(), ("F",))
|
||||
assert_equal(Image.new("P", (1, 1)).getbands(), ("P",))
|
||||
assert_equal(Image.new("RGB", (1, 1)).getbands(), ("R", "G", "B"))
|
||||
assert_equal(Image.new("RGBA", (1, 1)).getbands(), ("R", "G", "B", "A"))
|
||||
assert_equal(Image.new("CMYK", (1, 1)).getbands(), ("C", "M", "Y", "K"))
|
||||
assert_equal(Image.new("YCbCr", (1, 1)).getbands(), ("Y", "Cb", "Cr"))
|
||||
class TestImageGetBands(PillowTestCase):
|
||||
|
||||
def test_getbands(self):
|
||||
self.assertEqual(Image.new("1", (1, 1)).getbands(), ("1",))
|
||||
self.assertEqual(Image.new("L", (1, 1)).getbands(), ("L",))
|
||||
self.assertEqual(Image.new("I", (1, 1)).getbands(), ("I",))
|
||||
self.assertEqual(Image.new("F", (1, 1)).getbands(), ("F",))
|
||||
self.assertEqual(Image.new("P", (1, 1)).getbands(), ("P",))
|
||||
self.assertEqual(Image.new("RGB", (1, 1)).getbands(), ("R", "G", "B"))
|
||||
self.assertEqual(
|
||||
Image.new("RGBA", (1, 1)).getbands(), ("R", "G", "B", "A"))
|
||||
self.assertEqual(
|
||||
Image.new("CMYK", (1, 1)).getbands(), ("C", "M", "Y", "K"))
|
||||
self.assertEqual(
|
||||
Image.new("YCbCr", (1, 1)).getbands(), ("Y", "Cb", "Cr"))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,36 +1,45 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImageGetBbox(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
bbox = lena().getbbox()
|
||||
assert_true(isinstance(bbox, tuple))
|
||||
self.assertIsInstance(bbox, tuple)
|
||||
|
||||
def test_bbox():
|
||||
def test_bbox(self):
|
||||
|
||||
# 8-bit mode
|
||||
im = Image.new("L", (100, 100), 0)
|
||||
assert_equal(im.getbbox(), None)
|
||||
self.assertEqual(im.getbbox(), None)
|
||||
|
||||
im.paste(255, (10, 25, 90, 75))
|
||||
assert_equal(im.getbbox(), (10, 25, 90, 75))
|
||||
self.assertEqual(im.getbbox(), (10, 25, 90, 75))
|
||||
|
||||
im.paste(255, (25, 10, 75, 90))
|
||||
assert_equal(im.getbbox(), (10, 10, 90, 90))
|
||||
self.assertEqual(im.getbbox(), (10, 10, 90, 90))
|
||||
|
||||
im.paste(255, (-10, -10, 110, 110))
|
||||
assert_equal(im.getbbox(), (0, 0, 100, 100))
|
||||
self.assertEqual(im.getbbox(), (0, 0, 100, 100))
|
||||
|
||||
# 32-bit mode
|
||||
im = Image.new("RGB", (100, 100), 0)
|
||||
assert_equal(im.getbbox(), None)
|
||||
self.assertEqual(im.getbbox(), None)
|
||||
|
||||
im.paste(255, (10, 25, 90, 75))
|
||||
assert_equal(im.getbbox(), (10, 25, 90, 75))
|
||||
self.assertEqual(im.getbbox(), (10, 25, 90, 75))
|
||||
|
||||
im.paste(255, (25, 10, 75, 90))
|
||||
assert_equal(im.getbbox(), (10, 10, 90, 90))
|
||||
self.assertEqual(im.getbbox(), (10, 10, 90, 90))
|
||||
|
||||
im.paste(255, (-10, -10, 110, 110))
|
||||
assert_equal(im.getbbox(), (0, 0, 100, 100))
|
||||
self.assertEqual(im.getbbox(), (0, 0, 100, 100))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_getcolors():
|
||||
class TestImageGetColors(PillowTestCase):
|
||||
|
||||
def test_getcolors(self):
|
||||
|
||||
def getcolors(mode, limit=None):
|
||||
im = lena(mode)
|
||||
|
@ -14,51 +15,60 @@ def test_getcolors():
|
|||
return len(colors)
|
||||
return None
|
||||
|
||||
assert_equal(getcolors("1"), 2)
|
||||
assert_equal(getcolors("L"), 193)
|
||||
assert_equal(getcolors("I"), 193)
|
||||
assert_equal(getcolors("F"), 193)
|
||||
assert_equal(getcolors("P"), 54) # fixed palette
|
||||
assert_equal(getcolors("RGB"), None)
|
||||
assert_equal(getcolors("RGBA"), None)
|
||||
assert_equal(getcolors("CMYK"), None)
|
||||
assert_equal(getcolors("YCbCr"), None)
|
||||
self.assertEqual(getcolors("1"), 2)
|
||||
self.assertEqual(getcolors("L"), 193)
|
||||
self.assertEqual(getcolors("I"), 193)
|
||||
self.assertEqual(getcolors("F"), 193)
|
||||
self.assertEqual(getcolors("P"), 54) # fixed palette
|
||||
self.assertEqual(getcolors("RGB"), None)
|
||||
self.assertEqual(getcolors("RGBA"), None)
|
||||
self.assertEqual(getcolors("CMYK"), None)
|
||||
self.assertEqual(getcolors("YCbCr"), None)
|
||||
|
||||
assert_equal(getcolors("L", 128), None)
|
||||
assert_equal(getcolors("L", 1024), 193)
|
||||
self.assertEqual(getcolors("L", 128), None)
|
||||
self.assertEqual(getcolors("L", 1024), 193)
|
||||
|
||||
assert_equal(getcolors("RGB", 8192), None)
|
||||
assert_equal(getcolors("RGB", 16384), 14836)
|
||||
assert_equal(getcolors("RGB", 100000), 14836)
|
||||
self.assertEqual(getcolors("RGB", 8192), None)
|
||||
self.assertEqual(getcolors("RGB", 16384), 14836)
|
||||
self.assertEqual(getcolors("RGB", 100000), 14836)
|
||||
|
||||
assert_equal(getcolors("RGBA", 16384), 14836)
|
||||
assert_equal(getcolors("CMYK", 16384), 14836)
|
||||
assert_equal(getcolors("YCbCr", 16384), 11995)
|
||||
self.assertEqual(getcolors("RGBA", 16384), 14836)
|
||||
self.assertEqual(getcolors("CMYK", 16384), 14836)
|
||||
self.assertEqual(getcolors("YCbCr", 16384), 11995)
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
def test_pack():
|
||||
def test_pack(self):
|
||||
# Pack problems for small tables (@PIL209)
|
||||
|
||||
im = lena().quantize(3).convert("RGB")
|
||||
|
||||
expected = [(3236, (227, 183, 147)), (6297, (143, 84, 81)), (6851, (208, 143, 112))]
|
||||
expected = [
|
||||
(3236, (227, 183, 147)),
|
||||
(6297, (143, 84, 81)),
|
||||
(6851, (208, 143, 112))]
|
||||
|
||||
A = im.getcolors(maxcolors=2)
|
||||
assert_equal(A, None)
|
||||
self.assertEqual(A, None)
|
||||
|
||||
A = im.getcolors(maxcolors=3)
|
||||
A.sort()
|
||||
assert_equal(A, expected)
|
||||
self.assertEqual(A, expected)
|
||||
|
||||
A = im.getcolors(maxcolors=4)
|
||||
A.sort()
|
||||
assert_equal(A, expected)
|
||||
self.assertEqual(A, expected)
|
||||
|
||||
A = im.getcolors(maxcolors=8)
|
||||
A.sort()
|
||||
assert_equal(A, expected)
|
||||
self.assertEqual(A, expected)
|
||||
|
||||
A = im.getcolors(maxcolors=16)
|
||||
A.sort()
|
||||
assert_equal(A, expected)
|
||||
self.assertEqual(A, expected)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,28 +1,35 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
class TestImageGetData(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
data = lena().getdata()
|
||||
|
||||
assert_no_exception(lambda: len(data))
|
||||
assert_no_exception(lambda: list(data))
|
||||
len(data)
|
||||
list(data)
|
||||
|
||||
assert_equal(data[0], (223, 162, 133))
|
||||
self.assertEqual(data[0], (223, 162, 133))
|
||||
|
||||
def test_roundtrip():
|
||||
def test_roundtrip(self):
|
||||
|
||||
def getdata(mode):
|
||||
im = lena(mode).resize((32, 30))
|
||||
data = im.getdata()
|
||||
return data[0], len(data), len(list(data))
|
||||
|
||||
assert_equal(getdata("1"), (255, 960, 960))
|
||||
assert_equal(getdata("L"), (176, 960, 960))
|
||||
assert_equal(getdata("I"), (176, 960, 960))
|
||||
assert_equal(getdata("F"), (176.0, 960, 960))
|
||||
assert_equal(getdata("RGB"), ((223, 162, 133), 960, 960))
|
||||
assert_equal(getdata("RGBA"), ((223, 162, 133, 255), 960, 960))
|
||||
assert_equal(getdata("CMYK"), ((32, 93, 122, 0), 960, 960))
|
||||
assert_equal(getdata("YCbCr"), ((176, 103, 160), 960, 960))
|
||||
self.assertEqual(getdata("1"), (255, 960, 960))
|
||||
self.assertEqual(getdata("L"), (176, 960, 960))
|
||||
self.assertEqual(getdata("I"), (176, 960, 960))
|
||||
self.assertEqual(getdata("F"), (176.0, 960, 960))
|
||||
self.assertEqual(getdata("RGB"), ((223, 162, 133), 960, 960))
|
||||
self.assertEqual(getdata("RGBA"), ((223, 162, 133, 255), 960, 960))
|
||||
self.assertEqual(getdata("CMYK"), ((32, 93, 122, 0), 960, 960))
|
||||
self.assertEqual(getdata("YCbCr"), ((176, 103, 160), 960, 960))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_extrema():
|
||||
class TestImageGetExtrema(PillowTestCase):
|
||||
|
||||
def test_extrema(self):
|
||||
|
||||
def extrema(mode):
|
||||
return lena(mode).getextrema()
|
||||
|
||||
assert_equal(extrema("1"), (0, 255))
|
||||
assert_equal(extrema("L"), (40, 235))
|
||||
assert_equal(extrema("I"), (40, 235))
|
||||
assert_equal(extrema("F"), (40.0, 235.0))
|
||||
assert_equal(extrema("P"), (11, 218)) # fixed palette
|
||||
assert_equal(extrema("RGB"), ((61, 255), (26, 234), (44, 223)))
|
||||
assert_equal(extrema("RGBA"), ((61, 255), (26, 234), (44, 223), (255, 255)))
|
||||
assert_equal(extrema("CMYK"), ((0, 194), (21, 229), (32, 211), (0, 0)))
|
||||
self.assertEqual(extrema("1"), (0, 255))
|
||||
self.assertEqual(extrema("L"), (40, 235))
|
||||
self.assertEqual(extrema("I"), (40, 235))
|
||||
self.assertEqual(extrema("F"), (40.0, 235.0))
|
||||
self.assertEqual(extrema("P"), (11, 218)) # fixed palette
|
||||
self.assertEqual(
|
||||
extrema("RGB"), ((61, 255), (26, 234), (44, 223)))
|
||||
self.assertEqual(
|
||||
extrema("RGBA"), ((61, 255), (26, 234), (44, 223), (255, 255)))
|
||||
self.assertEqual(
|
||||
extrema("CMYK"), ((0, 194), (21, 229), (32, 211), (0, 0)))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena, py3
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
class TestImageGetIm(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
im = lena()
|
||||
type_repr = repr(type(im.getim()))
|
||||
|
||||
if py3:
|
||||
assert_true("PyCapsule" in type_repr)
|
||||
self.assertIn("PyCapsule", type_repr)
|
||||
|
||||
assert_true(isinstance(im.im.id, int))
|
||||
self.assertIsInstance(im.im.id, int)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,19 +1,26 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_palette():
|
||||
class TestImageGetPalette(PillowTestCase):
|
||||
|
||||
def test_palette(self):
|
||||
def palette(mode):
|
||||
p = lena(mode).getpalette()
|
||||
if p:
|
||||
return p[:10]
|
||||
return None
|
||||
assert_equal(palette("1"), None)
|
||||
assert_equal(palette("L"), None)
|
||||
assert_equal(palette("I"), None)
|
||||
assert_equal(palette("F"), None)
|
||||
assert_equal(palette("P"), [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
assert_equal(palette("RGB"), None)
|
||||
assert_equal(palette("RGBA"), None)
|
||||
assert_equal(palette("CMYK"), None)
|
||||
assert_equal(palette("YCbCr"), None)
|
||||
self.assertEqual(palette("1"), None)
|
||||
self.assertEqual(palette("L"), None)
|
||||
self.assertEqual(palette("I"), None)
|
||||
self.assertEqual(palette("F"), None)
|
||||
self.assertEqual(palette("P"), [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
self.assertEqual(palette("RGB"), None)
|
||||
self.assertEqual(palette("RGBA"), None)
|
||||
self.assertEqual(palette("CMYK"), None)
|
||||
self.assertEqual(palette("YCbCr"), None)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
Image.USE_CFFI_ACCESS = False
|
||||
|
||||
|
||||
def color(mode):
|
||||
bands = Image.getmodebands(mode)
|
||||
if bands == 1:
|
||||
|
@ -12,38 +13,41 @@ def color(mode):
|
|||
return tuple(range(1, bands+1))
|
||||
|
||||
|
||||
class TestImageGetPixel(PillowTestCase):
|
||||
|
||||
def check(mode, c=None):
|
||||
def check(self, mode, c=None):
|
||||
if not c:
|
||||
c = color(mode)
|
||||
|
||||
# check putpixel
|
||||
im = Image.new(mode, (1, 1), None)
|
||||
im.putpixel((0, 0), c)
|
||||
assert_equal(im.getpixel((0, 0)), c,
|
||||
"put/getpixel roundtrip failed for mode %s, color %s" %
|
||||
(mode, c))
|
||||
self.assertEqual(
|
||||
im.getpixel((0, 0)), c,
|
||||
"put/getpixel roundtrip failed for mode %s, color %s" % (mode, c))
|
||||
|
||||
# check inital color
|
||||
im = Image.new(mode, (1, 1), c)
|
||||
assert_equal(im.getpixel((0, 0)), c,
|
||||
"initial color failed for mode %s, color %s " %
|
||||
(mode, color))
|
||||
self.assertEqual(
|
||||
im.getpixel((0, 0)), c,
|
||||
"initial color failed for mode %s, color %s " % (mode, color))
|
||||
|
||||
def test_basic():
|
||||
def test_basic(self):
|
||||
for mode in ("1", "L", "LA", "I", "I;16", "I;16B", "F",
|
||||
"P", "PA", "RGB", "RGBA", "RGBX", "CMYK", "YCbCr"):
|
||||
check(mode)
|
||||
self.check(mode)
|
||||
|
||||
def test_signedness():
|
||||
# see https://github.com/python-imaging/Pillow/issues/452
|
||||
def test_signedness(self):
|
||||
# see https://github.com/python-pillow/Pillow/issues/452
|
||||
# pixelaccess is using signed int* instead of uint*
|
||||
for mode in ("I;16", "I;16B"):
|
||||
check(mode, 2**15-1)
|
||||
check(mode, 2**15)
|
||||
check(mode, 2**15+1)
|
||||
check(mode, 2**16-1)
|
||||
|
||||
self.check(mode, 2**15-1)
|
||||
self.check(mode, 2**15)
|
||||
self.check(mode, 2**15+1)
|
||||
self.check(mode, 2**16-1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,30 +1,38 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImageGetProjection(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
im = lena()
|
||||
|
||||
projection = im.getprojection()
|
||||
|
||||
assert_equal(len(projection), 2)
|
||||
assert_equal(len(projection[0]), im.size[0])
|
||||
assert_equal(len(projection[1]), im.size[1])
|
||||
self.assertEqual(len(projection), 2)
|
||||
self.assertEqual(len(projection[0]), im.size[0])
|
||||
self.assertEqual(len(projection[1]), im.size[1])
|
||||
|
||||
# 8-bit image
|
||||
im = Image.new("L", (10, 10))
|
||||
assert_equal(im.getprojection()[0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
assert_equal(im.getprojection()[1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
self.assertEqual(im.getprojection()[0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
self.assertEqual(im.getprojection()[1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
im.paste(255, (2, 4, 8, 6))
|
||||
assert_equal(im.getprojection()[0], [0, 0, 1, 1, 1, 1, 1, 1, 0, 0])
|
||||
assert_equal(im.getprojection()[1], [0, 0, 0, 0, 1, 1, 0, 0, 0, 0])
|
||||
self.assertEqual(im.getprojection()[0], [0, 0, 1, 1, 1, 1, 1, 1, 0, 0])
|
||||
self.assertEqual(im.getprojection()[1], [0, 0, 0, 0, 1, 1, 0, 0, 0, 0])
|
||||
|
||||
# 32-bit image
|
||||
im = Image.new("RGB", (10, 10))
|
||||
assert_equal(im.getprojection()[0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
assert_equal(im.getprojection()[1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
self.assertEqual(im.getprojection()[0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
self.assertEqual(im.getprojection()[1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
im.paste(255, (2, 4, 8, 6))
|
||||
assert_equal(im.getprojection()[0], [0, 0, 1, 1, 1, 1, 1, 1, 0, 0])
|
||||
assert_equal(im.getprojection()[1], [0, 0, 0, 0, 1, 1, 0, 0, 0, 0])
|
||||
self.assertEqual(im.getprojection()[0], [0, 0, 1, 1, 1, 1, 1, 1, 0, 0])
|
||||
self.assertEqual(im.getprojection()[1], [0, 0, 0, 0, 1, 1, 0, 0, 0, 0])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,19 +1,26 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_histogram():
|
||||
class TestImageHistogram(PillowTestCase):
|
||||
|
||||
def test_histogram(self):
|
||||
|
||||
def histogram(mode):
|
||||
h = lena(mode).histogram()
|
||||
return len(h), min(h), max(h)
|
||||
|
||||
assert_equal(histogram("1"), (256, 0, 8872))
|
||||
assert_equal(histogram("L"), (256, 0, 199))
|
||||
assert_equal(histogram("I"), (256, 0, 199))
|
||||
assert_equal(histogram("F"), (256, 0, 199))
|
||||
assert_equal(histogram("P"), (256, 0, 2912))
|
||||
assert_equal(histogram("RGB"), (768, 0, 285))
|
||||
assert_equal(histogram("RGBA"), (1024, 0, 16384))
|
||||
assert_equal(histogram("CMYK"), (1024, 0, 16384))
|
||||
assert_equal(histogram("YCbCr"), (768, 0, 741))
|
||||
self.assertEqual(histogram("1"), (256, 0, 8872))
|
||||
self.assertEqual(histogram("L"), (256, 0, 199))
|
||||
self.assertEqual(histogram("I"), (256, 0, 199))
|
||||
self.assertEqual(histogram("F"), (256, 0, 199))
|
||||
self.assertEqual(histogram("P"), (256, 0, 2912))
|
||||
self.assertEqual(histogram("RGB"), (768, 0, 285))
|
||||
self.assertEqual(histogram("RGBA"), (1024, 0, 16384))
|
||||
self.assertEqual(histogram("CMYK"), (1024, 0, 16384))
|
||||
self.assertEqual(histogram("YCbCr"), (768, 0, 741))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
import os
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImageLoad(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
im = lena()
|
||||
|
||||
pix = im.load()
|
||||
|
||||
assert_equal(pix[0, 0], (223, 162, 133))
|
||||
self.assertEqual(pix[0, 0], (223, 162, 133))
|
||||
|
||||
def test_close():
|
||||
def test_close(self):
|
||||
im = Image.open("Images/lena.gif")
|
||||
assert_no_exception(lambda: im.close())
|
||||
assert_exception(ValueError, lambda: im.load())
|
||||
assert_exception(ValueError, lambda: im.getpixel((0,0)))
|
||||
im.close()
|
||||
self.assertRaises(ValueError, lambda: im.load())
|
||||
self.assertRaises(ValueError, lambda: im.getpixel((0, 0)))
|
||||
|
||||
def test_contextmanager():
|
||||
def test_contextmanager(self):
|
||||
fn = None
|
||||
with Image.open("Images/lena.gif") as im:
|
||||
fn = im.fp.fileno()
|
||||
assert_no_exception(lambda: os.fstat(fn))
|
||||
os.fstat(fn)
|
||||
|
||||
assert_exception(OSError, lambda: os.fstat(fn))
|
||||
self.assertRaises(OSError, lambda: os.fstat(fn))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImageMode(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
im = lena()
|
||||
assert_no_exception(lambda: im.mode)
|
||||
im.mode
|
||||
|
||||
def test_properties():
|
||||
def test_properties(self):
|
||||
def check(mode, *result):
|
||||
signature = (
|
||||
Image.getmodebase(mode), Image.getmodetype(mode),
|
||||
Image.getmodebands(mode), Image.getmodebandnames(mode),
|
||||
)
|
||||
assert_equal(signature, result)
|
||||
self.assertEqual(signature, result)
|
||||
check("1", "L", "L", 1, ("1",))
|
||||
check("L", "L", "L", 1, ("L",))
|
||||
check("P", "RGB", "L", 1, ("P",))
|
||||
|
@ -25,3 +28,9 @@ def test_properties():
|
|||
check("RGBX", "RGB", "L", 4, ("R", "G", "B", "X"))
|
||||
check("CMYK", "RGB", "L", 4, ("C", "M", "Y", "K"))
|
||||
check("YCbCr", "RGB", "L", 3, ("Y", "Cb", "Cr"))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_offset():
|
||||
class TestImageOffset(PillowTestCase):
|
||||
|
||||
def test_offset(self):
|
||||
|
||||
im1 = lena()
|
||||
|
||||
im2 = assert_warning(DeprecationWarning, lambda: im1.offset(10))
|
||||
assert_equal(im1.getpixel((0, 0)), im2.getpixel((10, 10)))
|
||||
im2 = self.assert_warning(DeprecationWarning, lambda: im1.offset(10))
|
||||
self.assertEqual(im1.getpixel((0, 0)), im2.getpixel((10, 10)))
|
||||
|
||||
im2 = assert_warning(DeprecationWarning, lambda: im1.offset(10, 20))
|
||||
assert_equal(im1.getpixel((0, 0)), im2.getpixel((10, 20)))
|
||||
im2 = self.assert_warning(
|
||||
DeprecationWarning, lambda: im1.offset(10, 20))
|
||||
self.assertEqual(im1.getpixel((0, 0)), im2.getpixel((10, 20)))
|
||||
|
||||
im2 = assert_warning(DeprecationWarning, lambda: im1.offset(20, 20))
|
||||
assert_equal(im1.getpixel((0, 0)), im2.getpixel((20, 20)))
|
||||
im2 = self.assert_warning(
|
||||
DeprecationWarning, lambda: im1.offset(20, 20))
|
||||
self.assertEqual(im1.getpixel((0, 0)), im2.getpixel((20, 20)))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
from tester import *
|
||||
|
||||
from PIL import Image
|
||||
|
||||
success()
|
|
@ -1,33 +1,41 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
import sys
|
||||
|
||||
|
||||
class TestImagePoint(PillowTestCase):
|
||||
|
||||
def setUp(self):
|
||||
if hasattr(sys, 'pypy_version_info'):
|
||||
# This takes _forever_ on pypy. Open Bug,
|
||||
# see https://github.com/python-imaging/Pillow/issues/484
|
||||
skip()
|
||||
|
||||
def test_sanity():
|
||||
# This takes _forever_ on PyPy. Open Bug,
|
||||
# see https://github.com/python-pillow/Pillow/issues/484
|
||||
self.skipTest("Too slow on PyPy")
|
||||
|
||||
def test_sanity(self):
|
||||
im = lena()
|
||||
|
||||
assert_exception(ValueError, lambda: im.point(list(range(256))))
|
||||
assert_no_exception(lambda: im.point(list(range(256))*3))
|
||||
assert_no_exception(lambda: im.point(lambda x: x))
|
||||
self.assertRaises(ValueError, lambda: im.point(list(range(256))))
|
||||
im.point(list(range(256))*3)
|
||||
im.point(lambda x: x)
|
||||
|
||||
im = im.convert("I")
|
||||
assert_exception(ValueError, lambda: im.point(list(range(256))))
|
||||
assert_no_exception(lambda: im.point(lambda x: x*1))
|
||||
assert_no_exception(lambda: im.point(lambda x: x+1))
|
||||
assert_no_exception(lambda: im.point(lambda x: x*1+1))
|
||||
assert_exception(TypeError, lambda: im.point(lambda x: x-1))
|
||||
assert_exception(TypeError, lambda: im.point(lambda x: x/1))
|
||||
self.assertRaises(ValueError, lambda: im.point(list(range(256))))
|
||||
im.point(lambda x: x*1)
|
||||
im.point(lambda x: x+1)
|
||||
im.point(lambda x: x*1+1)
|
||||
self.assertRaises(TypeError, lambda: im.point(lambda x: x-1))
|
||||
self.assertRaises(TypeError, lambda: im.point(lambda x: x/1))
|
||||
|
||||
|
||||
def test_16bit_lut():
|
||||
def test_16bit_lut(self):
|
||||
""" Tests for 16 bit -> 8 bit lut for converting I->L images
|
||||
see https://github.com/python-imaging/Pillow/issues/440
|
||||
see https://github.com/python-pillow/Pillow/issues/440
|
||||
"""
|
||||
|
||||
im = lena("I")
|
||||
assert_no_exception(lambda: im.point(list(range(256))*256, 'L'))
|
||||
im.point(list(range(256))*256, 'L')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,43 +1,52 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_interface():
|
||||
|
||||
class TestImagePutAlpha(PillowTestCase):
|
||||
|
||||
def test_interface(self):
|
||||
|
||||
im = Image.new("RGBA", (1, 1), (1, 2, 3, 0))
|
||||
assert_equal(im.getpixel((0, 0)), (1, 2, 3, 0))
|
||||
self.assertEqual(im.getpixel((0, 0)), (1, 2, 3, 0))
|
||||
|
||||
im = Image.new("RGBA", (1, 1), (1, 2, 3))
|
||||
assert_equal(im.getpixel((0, 0)), (1, 2, 3, 255))
|
||||
self.assertEqual(im.getpixel((0, 0)), (1, 2, 3, 255))
|
||||
|
||||
im.putalpha(Image.new("L", im.size, 4))
|
||||
assert_equal(im.getpixel((0, 0)), (1, 2, 3, 4))
|
||||
self.assertEqual(im.getpixel((0, 0)), (1, 2, 3, 4))
|
||||
|
||||
im.putalpha(5)
|
||||
assert_equal(im.getpixel((0, 0)), (1, 2, 3, 5))
|
||||
self.assertEqual(im.getpixel((0, 0)), (1, 2, 3, 5))
|
||||
|
||||
def test_promote():
|
||||
def test_promote(self):
|
||||
|
||||
im = Image.new("L", (1, 1), 1)
|
||||
assert_equal(im.getpixel((0, 0)), 1)
|
||||
self.assertEqual(im.getpixel((0, 0)), 1)
|
||||
|
||||
im.putalpha(2)
|
||||
assert_equal(im.mode, 'LA')
|
||||
assert_equal(im.getpixel((0, 0)), (1, 2))
|
||||
self.assertEqual(im.mode, 'LA')
|
||||
self.assertEqual(im.getpixel((0, 0)), (1, 2))
|
||||
|
||||
im = Image.new("RGB", (1, 1), (1, 2, 3))
|
||||
assert_equal(im.getpixel((0, 0)), (1, 2, 3))
|
||||
self.assertEqual(im.getpixel((0, 0)), (1, 2, 3))
|
||||
|
||||
im.putalpha(4)
|
||||
assert_equal(im.mode, 'RGBA')
|
||||
assert_equal(im.getpixel((0, 0)), (1, 2, 3, 4))
|
||||
self.assertEqual(im.mode, 'RGBA')
|
||||
self.assertEqual(im.getpixel((0, 0)), (1, 2, 3, 4))
|
||||
|
||||
def test_readonly():
|
||||
def test_readonly(self):
|
||||
|
||||
im = Image.new("RGB", (1, 1), (1, 2, 3))
|
||||
im.readonly = 1
|
||||
|
||||
im.putalpha(4)
|
||||
assert_false(im.readonly)
|
||||
assert_equal(im.mode, 'RGBA')
|
||||
assert_equal(im.getpixel((0, 0)), (1, 2, 3, 4))
|
||||
self.assertFalse(im.readonly)
|
||||
self.assertEqual(im.mode, 'RGBA')
|
||||
self.assertEqual(im.getpixel((0, 0)), (1, 2, 3, 4))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
import sys
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImagePutData(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
im1 = lena()
|
||||
|
||||
|
@ -13,28 +16,33 @@ def test_sanity():
|
|||
im2 = Image.new(im1.mode, im1.size, 0)
|
||||
im2.putdata(data)
|
||||
|
||||
assert_image_equal(im1, im2)
|
||||
self.assert_image_equal(im1, im2)
|
||||
|
||||
# readonly
|
||||
im2 = Image.new(im1.mode, im2.size, 0)
|
||||
im2.readonly = 1
|
||||
im2.putdata(data)
|
||||
|
||||
assert_false(im2.readonly)
|
||||
assert_image_equal(im1, im2)
|
||||
self.assertFalse(im2.readonly)
|
||||
self.assert_image_equal(im1, im2)
|
||||
|
||||
|
||||
def test_long_integers():
|
||||
def test_long_integers(self):
|
||||
# see bug-200802-systemerror
|
||||
def put(value):
|
||||
im = Image.new("RGBA", (1, 1))
|
||||
im.putdata([value])
|
||||
return im.getpixel((0, 0))
|
||||
assert_equal(put(0xFFFFFFFF), (255, 255, 255, 255))
|
||||
assert_equal(put(0xFFFFFFFF), (255, 255, 255, 255))
|
||||
assert_equal(put(-1), (255, 255, 255, 255))
|
||||
assert_equal(put(-1), (255, 255, 255, 255))
|
||||
self.assertEqual(put(0xFFFFFFFF), (255, 255, 255, 255))
|
||||
self.assertEqual(put(0xFFFFFFFF), (255, 255, 255, 255))
|
||||
self.assertEqual(put(-1), (255, 255, 255, 255))
|
||||
self.assertEqual(put(-1), (255, 255, 255, 255))
|
||||
if sys.maxsize > 2**32:
|
||||
assert_equal(put(sys.maxsize), (255, 255, 255, 255))
|
||||
self.assertEqual(put(sys.maxsize), (255, 255, 255, 255))
|
||||
else:
|
||||
assert_equal(put(sys.maxsize), (255, 255, 255, 127))
|
||||
self.assertEqual(put(sys.maxsize), (255, 255, 255, 127))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
from PIL import ImagePalette
|
||||
|
||||
def test_putpalette():
|
||||
|
||||
class TestImagePutPalette(PillowTestCase):
|
||||
|
||||
def test_putpalette(self):
|
||||
def palette(mode):
|
||||
im = lena(mode).copy()
|
||||
im.putpalette(list(range(256))*3)
|
||||
|
@ -11,18 +13,24 @@ def test_putpalette():
|
|||
if p:
|
||||
return im.mode, p[:10]
|
||||
return im.mode
|
||||
assert_exception(ValueError, lambda: palette("1"))
|
||||
assert_equal(palette("L"), ("P", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
|
||||
assert_equal(palette("P"), ("P", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
|
||||
assert_exception(ValueError, lambda: palette("I"))
|
||||
assert_exception(ValueError, lambda: palette("F"))
|
||||
assert_exception(ValueError, lambda: palette("RGB"))
|
||||
assert_exception(ValueError, lambda: palette("RGBA"))
|
||||
assert_exception(ValueError, lambda: palette("YCbCr"))
|
||||
self.assertRaises(ValueError, lambda: palette("1"))
|
||||
self.assertEqual(palette("L"), ("P", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
|
||||
self.assertEqual(palette("P"), ("P", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
|
||||
self.assertRaises(ValueError, lambda: palette("I"))
|
||||
self.assertRaises(ValueError, lambda: palette("F"))
|
||||
self.assertRaises(ValueError, lambda: palette("RGB"))
|
||||
self.assertRaises(ValueError, lambda: palette("RGBA"))
|
||||
self.assertRaises(ValueError, lambda: palette("YCbCr"))
|
||||
|
||||
def test_imagepalette():
|
||||
def test_imagepalette(self):
|
||||
im = lena("P")
|
||||
assert_no_exception(lambda: im.putpalette(ImagePalette.negative()))
|
||||
assert_no_exception(lambda: im.putpalette(ImagePalette.random()))
|
||||
assert_no_exception(lambda: im.putpalette(ImagePalette.sepia()))
|
||||
assert_no_exception(lambda: im.putpalette(ImagePalette.wedge()))
|
||||
im.putpalette(ImagePalette.negative())
|
||||
im.putpalette(ImagePalette.random())
|
||||
im.putpalette(ImagePalette.sepia())
|
||||
im.putpalette(ImagePalette.wedge())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
Image.USE_CFFI_ACCESS = False
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImagePutPixel(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
|
||||
im1 = lena()
|
||||
im2 = Image.new(im1.mode, im1.size, 0)
|
||||
|
@ -14,7 +17,7 @@ def test_sanity():
|
|||
pos = x, y
|
||||
im2.putpixel(pos, im1.getpixel(pos))
|
||||
|
||||
assert_image_equal(im1, im2)
|
||||
self.assert_image_equal(im1, im2)
|
||||
|
||||
im2 = Image.new(im1.mode, im1.size, 0)
|
||||
im2.readonly = 1
|
||||
|
@ -24,8 +27,8 @@ def test_sanity():
|
|||
pos = x, y
|
||||
im2.putpixel(pos, im1.getpixel(pos))
|
||||
|
||||
assert_false(im2.readonly)
|
||||
assert_image_equal(im1, im2)
|
||||
self.assertFalse(im2.readonly)
|
||||
self.assert_image_equal(im1, im2)
|
||||
|
||||
im2 = Image.new(im1.mode, im1.size, 0)
|
||||
|
||||
|
@ -36,10 +39,12 @@ def test_sanity():
|
|||
for x in range(im1.size[0]):
|
||||
pix2[x, y] = pix1[x, y]
|
||||
|
||||
assert_image_equal(im1, im2)
|
||||
|
||||
|
||||
|
||||
self.assert_image_equal(im1, im2)
|
||||
|
||||
# see test_image_getpixel for more tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_sanity():
|
||||
|
||||
class TestImageQuantize(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
im = lena()
|
||||
|
||||
im = im.quantize()
|
||||
assert_image(im, "P", im.size)
|
||||
self.assert_image(im, "P", im.size)
|
||||
|
||||
im = lena()
|
||||
im = im.quantize(palette=lena("P"))
|
||||
assert_image(im, "P", im.size)
|
||||
self.assert_image(im, "P", im.size)
|
||||
|
||||
def test_octree_quantize():
|
||||
def test_octree_quantize(self):
|
||||
im = lena()
|
||||
|
||||
im = im.quantize(100, Image.FASTOCTREE)
|
||||
assert_image(im, "P", im.size)
|
||||
self.assert_image(im, "P", im.size)
|
||||
|
||||
assert len(im.getcolors()) == 100
|
||||
|
||||
def test_rgba_quantize():
|
||||
def test_rgba_quantize(self):
|
||||
im = lena('RGBA')
|
||||
assert_no_exception(lambda: im.quantize())
|
||||
assert_exception(Exception, lambda: im.quantize(method=0))
|
||||
im.quantize()
|
||||
self.assertRaises(Exception, lambda: im.quantize(method=0))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_resize():
|
||||
class TestImageResize(PillowTestCase):
|
||||
|
||||
def test_resize(self):
|
||||
def resize(mode, size):
|
||||
out = lena(mode).resize(size)
|
||||
assert_equal(out.mode, mode)
|
||||
assert_equal(out.size, size)
|
||||
self.assertEqual(out.mode, mode)
|
||||
self.assertEqual(out.size, size)
|
||||
for mode in "1", "P", "L", "RGB", "I", "F":
|
||||
yield_test(resize, mode, (100, 100))
|
||||
yield_test(resize, mode, (200, 200))
|
||||
resize(mode, (100, 100))
|
||||
resize(mode, (200, 200))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_rotate():
|
||||
class TestImageRotate(PillowTestCase):
|
||||
|
||||
def test_rotate(self):
|
||||
def rotate(mode):
|
||||
im = lena(mode)
|
||||
out = im.rotate(45)
|
||||
assert_equal(out.mode, mode)
|
||||
assert_equal(out.size, im.size) # default rotate clips output
|
||||
self.assertEqual(out.mode, mode)
|
||||
self.assertEqual(out.size, im.size) # default rotate clips output
|
||||
out = im.rotate(45, expand=1)
|
||||
assert_equal(out.mode, mode)
|
||||
assert_true(out.size != im.size)
|
||||
self.assertEqual(out.mode, mode)
|
||||
self.assertNotEqual(out.size, im.size)
|
||||
for mode in "1", "P", "L", "RGB", "I", "F":
|
||||
yield_test(rotate, mode)
|
||||
rotate(mode)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
from tester import *
|
||||
|
||||
from PIL import Image
|
||||
|
||||
success()
|
|
@ -1,5 +0,0 @@
|
|||
from tester import *
|
||||
|
||||
from PIL import Image
|
||||
|
||||
success()
|
|
@ -1,5 +0,0 @@
|
|||
from tester import *
|
||||
|
||||
from PIL import Image
|
||||
|
||||
success()
|
|
@ -1,49 +1,67 @@
|
|||
from tester import *
|
||||
from helper import unittest, PillowTestCase, tearDownModule, lena
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def test_split():
|
||||
|
||||
class TestImageSplit(PillowTestCase):
|
||||
|
||||
def test_split(self):
|
||||
def split(mode):
|
||||
layers = lena(mode).split()
|
||||
return [(i.mode, i.size[0], i.size[1]) for i in layers]
|
||||
assert_equal(split("1"), [('1', 128, 128)])
|
||||
assert_equal(split("L"), [('L', 128, 128)])
|
||||
assert_equal(split("I"), [('I', 128, 128)])
|
||||
assert_equal(split("F"), [('F', 128, 128)])
|
||||
assert_equal(split("P"), [('P', 128, 128)])
|
||||
assert_equal(split("RGB"), [('L', 128, 128), ('L', 128, 128), ('L', 128, 128)])
|
||||
assert_equal(split("RGBA"), [('L', 128, 128), ('L', 128, 128), ('L', 128, 128), ('L', 128, 128)])
|
||||
assert_equal(split("CMYK"), [('L', 128, 128), ('L', 128, 128), ('L', 128, 128), ('L', 128, 128)])
|
||||
assert_equal(split("YCbCr"), [('L', 128, 128), ('L', 128, 128), ('L', 128, 128)])
|
||||
self.assertEqual(split("1"), [('1', 128, 128)])
|
||||
self.assertEqual(split("L"), [('L', 128, 128)])
|
||||
self.assertEqual(split("I"), [('I', 128, 128)])
|
||||
self.assertEqual(split("F"), [('F', 128, 128)])
|
||||
self.assertEqual(split("P"), [('P', 128, 128)])
|
||||
self.assertEqual(
|
||||
split("RGB"), [('L', 128, 128), ('L', 128, 128), ('L', 128, 128)])
|
||||
self.assertEqual(
|
||||
split("RGBA"),
|
||||
[('L', 128, 128), ('L', 128, 128),
|
||||
('L', 128, 128), ('L', 128, 128)])
|
||||
self.assertEqual(
|
||||
split("CMYK"),
|
||||
[('L', 128, 128), ('L', 128, 128),
|
||||
('L', 128, 128), ('L', 128, 128)])
|
||||
self.assertEqual(
|
||||
split("YCbCr"),
|
||||
[('L', 128, 128), ('L', 128, 128), ('L', 128, 128)])
|
||||
|
||||
def test_split_merge():
|
||||
def test_split_merge(self):
|
||||
def split_merge(mode):
|
||||
return Image.merge(mode, lena(mode).split())
|
||||
assert_image_equal(lena("1"), split_merge("1"))
|
||||
assert_image_equal(lena("L"), split_merge("L"))
|
||||
assert_image_equal(lena("I"), split_merge("I"))
|
||||
assert_image_equal(lena("F"), split_merge("F"))
|
||||
assert_image_equal(lena("P"), split_merge("P"))
|
||||
assert_image_equal(lena("RGB"), split_merge("RGB"))
|
||||
assert_image_equal(lena("RGBA"), split_merge("RGBA"))
|
||||
assert_image_equal(lena("CMYK"), split_merge("CMYK"))
|
||||
assert_image_equal(lena("YCbCr"), split_merge("YCbCr"))
|
||||
self.assert_image_equal(lena("1"), split_merge("1"))
|
||||
self.assert_image_equal(lena("L"), split_merge("L"))
|
||||
self.assert_image_equal(lena("I"), split_merge("I"))
|
||||
self.assert_image_equal(lena("F"), split_merge("F"))
|
||||
self.assert_image_equal(lena("P"), split_merge("P"))
|
||||
self.assert_image_equal(lena("RGB"), split_merge("RGB"))
|
||||
self.assert_image_equal(lena("RGBA"), split_merge("RGBA"))
|
||||
self.assert_image_equal(lena("CMYK"), split_merge("CMYK"))
|
||||
self.assert_image_equal(lena("YCbCr"), split_merge("YCbCr"))
|
||||
|
||||
def test_split_open():
|
||||
def test_split_open(self):
|
||||
codecs = dir(Image.core)
|
||||
|
||||
if 'zip_encoder' in codecs:
|
||||
file = tempfile("temp.png")
|
||||
file = self.tempfile("temp.png")
|
||||
else:
|
||||
file = tempfile("temp.pcx")
|
||||
file = self.tempfile("temp.pcx")
|
||||
|
||||
def split_open(mode):
|
||||
lena(mode).save(file)
|
||||
im = Image.open(file)
|
||||
return len(im.split())
|
||||
assert_equal(split_open("1"), 1)
|
||||
assert_equal(split_open("L"), 1)
|
||||
assert_equal(split_open("P"), 1)
|
||||
assert_equal(split_open("RGB"), 3)
|
||||
self.assertEqual(split_open("1"), 1)
|
||||
self.assertEqual(split_open("L"), 1)
|
||||
self.assertEqual(split_open("P"), 1)
|
||||
self.assertEqual(split_open("RGB"), 3)
|
||||
if 'zip_encoder' in codecs:
|
||||
assert_equal(split_open("RGBA"), 4)
|
||||
self.assertEqual(split_open("RGBA"), 4)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
# End of file
|
||||
|
|