mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 01:46:18 +03:00
Merge with master
This commit is contained in:
commit
ab87302560
|
@ -40,9 +40,7 @@ script:
|
|||
- CFLAGS="-coverage" python setup.py build_ext --inplace
|
||||
|
||||
- coverage run --append --include=PIL/* selftest.py
|
||||
# Temporarily remove fail-fast
|
||||
# - coverage run --append --include=PIL/* -m nose -vx Tests/test_*.py
|
||||
- coverage run --append --include=PIL/* -m nose -v Tests/test_*.py
|
||||
- coverage run --append --include=PIL/* -m nose -vx Tests/test_*.py
|
||||
|
||||
after_success:
|
||||
# gather the coverage data
|
||||
|
|
|
@ -4,6 +4,9 @@ Changelog (Pillow)
|
|||
2.6.0 (unreleased)
|
||||
------------------
|
||||
|
||||
- Image.tobytes() and Image.tostring() documentation update #916 #917
|
||||
[mgedmin]
|
||||
|
||||
- On Windows, do not execute convert.exe without specifying path #912
|
||||
[cgohlke]
|
||||
|
||||
|
|
|
@ -664,6 +664,10 @@ class Image:
|
|||
|
||||
# Declare tostring as alias to tobytes
|
||||
def tostring(self, *args, **kw):
|
||||
"""Deprecated alias to tobytes.
|
||||
|
||||
.. deprecated:: 2.0
|
||||
"""
|
||||
warnings.warn(
|
||||
'tostring() is deprecated. Please call tobytes() instead.',
|
||||
DeprecationWarning,
|
||||
|
|
|
@ -23,23 +23,26 @@ from PIL import Image
|
|||
|
||||
class HDC:
|
||||
"""
|
||||
Wraps a HDC integer. The resulting object can be passed to the
|
||||
Wraps an HDC integer. The resulting object can be passed to the
|
||||
:py:meth:`~PIL.ImageWin.Dib.draw` and :py:meth:`~PIL.ImageWin.Dib.expose`
|
||||
methods.
|
||||
"""
|
||||
def __init__(self, dc):
|
||||
self.dc = dc
|
||||
|
||||
def __int__(self):
|
||||
return self.dc
|
||||
|
||||
|
||||
class HWND:
|
||||
"""
|
||||
Wraps a HWND integer. The resulting object can be passed to the
|
||||
Wraps an HWND integer. The resulting object can be passed to the
|
||||
:py:meth:`~PIL.ImageWin.Dib.draw` and :py:meth:`~PIL.ImageWin.Dib.expose`
|
||||
methods, instead of a DC.
|
||||
"""
|
||||
def __init__(self, wnd):
|
||||
self.wnd = wnd
|
||||
|
||||
def __int__(self):
|
||||
return self.wnd
|
||||
|
||||
|
@ -79,13 +82,12 @@ class Dib:
|
|||
if image:
|
||||
self.paste(image)
|
||||
|
||||
|
||||
def expose(self, handle):
|
||||
"""
|
||||
Copy the bitmap contents to a device context.
|
||||
|
||||
:param handle: Device context (HDC), cast to a Python integer, or a HDC
|
||||
or HWND instance. In PythonWin, you can use the
|
||||
:param handle: Device context (HDC), cast to a Python integer, or an
|
||||
HDC or HWND instance. In PythonWin, you can use the
|
||||
:py:meth:`CDC.GetHandleAttrib` to get a suitable handle.
|
||||
"""
|
||||
if isinstance(handle, HWND):
|
||||
|
@ -109,7 +111,7 @@ class Dib:
|
|||
necessary.
|
||||
"""
|
||||
if not src:
|
||||
src = (0,0) + self.size
|
||||
src = (0, 0) + self.size
|
||||
if isinstance(handle, HWND):
|
||||
dc = self.image.getdc(handle)
|
||||
try:
|
||||
|
@ -120,7 +122,6 @@ class Dib:
|
|||
result = self.image.draw(handle, dst, src)
|
||||
return result
|
||||
|
||||
|
||||
def query_palette(self, handle):
|
||||
"""
|
||||
Installs the palette associated with the image in the given device
|
||||
|
@ -146,7 +147,6 @@ class Dib:
|
|||
result = self.image.query_palette(handle)
|
||||
return result
|
||||
|
||||
|
||||
def paste(self, im, box=None):
|
||||
"""
|
||||
Paste a PIL image into the bitmap image.
|
||||
|
@ -166,7 +166,6 @@ class Dib:
|
|||
else:
|
||||
self.image.paste(im.im)
|
||||
|
||||
|
||||
def frombytes(self, buffer):
|
||||
"""
|
||||
Load display memory contents from byte data.
|
||||
|
@ -176,7 +175,6 @@ class Dib:
|
|||
"""
|
||||
return self.image.frombytes(buffer)
|
||||
|
||||
|
||||
def tobytes(self):
|
||||
"""
|
||||
Copy display memory contents to bytes object.
|
||||
|
@ -204,6 +202,7 @@ class Dib:
|
|||
)
|
||||
return self.tobytes()
|
||||
|
||||
|
||||
##
|
||||
# Create a Window with the given title size.
|
||||
|
||||
|
@ -235,6 +234,7 @@ class Window:
|
|||
def mainloop(self):
|
||||
Image.core.eventloop()
|
||||
|
||||
|
||||
##
|
||||
# Create an image window which displays the given image.
|
||||
|
||||
|
|
|
@ -1,16 +1,123 @@
|
|||
from helper import unittest, PillowTestCase
|
||||
from helper import unittest, PillowTestCase, hopper
|
||||
|
||||
from PIL import Image
|
||||
from PIL import ImageWin
|
||||
import sys
|
||||
|
||||
|
||||
class TestImageWin(PillowTestCase):
|
||||
|
||||
def test_sanity(self):
|
||||
dir(Image)
|
||||
dir(ImageWin)
|
||||
pass
|
||||
|
||||
def test_hdc(self):
|
||||
# Arrange
|
||||
dc = 50
|
||||
|
||||
# Act
|
||||
hdc = ImageWin.HDC(dc)
|
||||
dc2 = int(hdc)
|
||||
|
||||
# Assert
|
||||
self.assertEqual(dc2, 50)
|
||||
|
||||
def test_hwnd(self):
|
||||
# Arrange
|
||||
wnd = 50
|
||||
|
||||
# Act
|
||||
hwnd = ImageWin.HWND(wnd)
|
||||
wnd2 = int(hwnd)
|
||||
|
||||
# Assert
|
||||
self.assertEqual(wnd2, 50)
|
||||
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith('win32'), "Windows only")
|
||||
class TestImageWinDib(PillowTestCase):
|
||||
|
||||
def test_dib_image(self):
|
||||
# Arrange
|
||||
im = hopper()
|
||||
|
||||
# Act
|
||||
dib = ImageWin.Dib(im)
|
||||
|
||||
# Assert
|
||||
self.assertEqual(dib.size, im.size)
|
||||
|
||||
def test_dib_mode_string(self):
|
||||
# Arrange
|
||||
mode = "RGBA"
|
||||
size = (128, 128)
|
||||
|
||||
# Act
|
||||
dib = ImageWin.Dib(mode, size)
|
||||
|
||||
# Assert
|
||||
self.assertEqual(dib.size, (128, 128))
|
||||
|
||||
def test_dib_paste(self):
|
||||
# Arrange
|
||||
im = hopper()
|
||||
|
||||
mode = "RGBA"
|
||||
size = (128, 128)
|
||||
dib = ImageWin.Dib(mode, size)
|
||||
|
||||
# Act
|
||||
dib.paste(im)
|
||||
|
||||
# Assert
|
||||
self.assertEqual(dib.size, (128, 128))
|
||||
|
||||
def test_dib_paste_bbox(self):
|
||||
# Arrange
|
||||
im = hopper()
|
||||
bbox = (0, 0, 10, 10)
|
||||
|
||||
mode = "RGBA"
|
||||
size = (128, 128)
|
||||
dib = ImageWin.Dib(mode, size)
|
||||
|
||||
# Act
|
||||
dib.paste(im, bbox)
|
||||
|
||||
# Assert
|
||||
self.assertEqual(dib.size, (128, 128))
|
||||
|
||||
def test_dib_frombytes_tobytes_roundtrip(self):
|
||||
# Arrange
|
||||
# Make two different DIB images
|
||||
im = hopper()
|
||||
dib1 = ImageWin.Dib(im)
|
||||
|
||||
mode = "RGB"
|
||||
size = (128, 128)
|
||||
dib2 = ImageWin.Dib(mode, size)
|
||||
|
||||
# Confirm they're different
|
||||
self.assertNotEqual(dib1.tobytes(), dib2.tobytes())
|
||||
|
||||
# Act
|
||||
# Make one the same as the using tobytes()/frombytes()
|
||||
buffer = dib1.tobytes()
|
||||
dib2.frombytes(buffer)
|
||||
|
||||
# Assert
|
||||
# Confirm they're the same
|
||||
self.assertEqual(dib1.tobytes(), dib2.tobytes())
|
||||
|
||||
def test_dib_fromstring_tostring_deprecated(self):
|
||||
# Arrange
|
||||
im = hopper()
|
||||
dib = ImageWin.Dib(im)
|
||||
buffer = dib.tobytes()
|
||||
|
||||
# Act/Assert
|
||||
self.assert_warning(DeprecationWarning, lambda: dib.tostring())
|
||||
self.assert_warning(DeprecationWarning, lambda: dib.fromstring(buffer))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -135,6 +135,7 @@ ITU-R 709, using the D65 luminant) to the CIE XYZ color space:
|
|||
.. automethod:: PIL.Image.Image.tell
|
||||
.. automethod:: PIL.Image.Image.thumbnail
|
||||
.. automethod:: PIL.Image.Image.tobitmap
|
||||
.. automethod:: PIL.Image.Image.tobytes
|
||||
.. automethod:: PIL.Image.Image.tostring
|
||||
.. automethod:: PIL.Image.Image.transform
|
||||
.. automethod:: PIL.Image.Image.transpose
|
||||
|
|
7
encode.c
7
encode.c
|
@ -535,7 +535,7 @@ PyImaging_ZipEncoderNew(PyObject* self, PyObject* args)
|
|||
|
||||
#include "Jpeg.h"
|
||||
|
||||
static unsigned int** get_qtables_arrays(PyObject* qtables) {
|
||||
static unsigned int** get_qtables_arrays(PyObject* qtables, int* qtablesLen) {
|
||||
PyObject* tables;
|
||||
PyObject* table;
|
||||
PyObject* table_data;
|
||||
|
@ -588,6 +588,7 @@ static unsigned int** get_qtables_arrays(PyObject* qtables) {
|
|||
}
|
||||
|
||||
Py_DECREF(tables);
|
||||
*qtablesLen = num_tables;
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
PyMem_Free(qarrays);
|
||||
|
@ -614,6 +615,7 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
|||
int subsampling = -1; /* -1=default, 0=none, 1=medium, 2=high */
|
||||
PyObject* qtables=NULL;
|
||||
unsigned int **qarrays = NULL;
|
||||
int qtablesLen = 0;
|
||||
char* extra = NULL;
|
||||
int extra_size;
|
||||
char* rawExif = NULL;
|
||||
|
@ -633,7 +635,7 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
|||
if (get_packer(encoder, mode, rawmode) < 0)
|
||||
return NULL;
|
||||
|
||||
qarrays = get_qtables_arrays(qtables);
|
||||
qarrays = get_qtables_arrays(qtables, &qtablesLen);
|
||||
|
||||
if (extra && extra_size > 0) {
|
||||
char* p = malloc(extra_size);
|
||||
|
@ -657,6 +659,7 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
|
|||
|
||||
((JPEGENCODERSTATE*)encoder->state.context)->quality = quality;
|
||||
((JPEGENCODERSTATE*)encoder->state.context)->qtables = qarrays;
|
||||
((JPEGENCODERSTATE*)encoder->state.context)->qtablesLen = qtablesLen;
|
||||
((JPEGENCODERSTATE*)encoder->state.context)->subsampling = subsampling;
|
||||
((JPEGENCODERSTATE*)encoder->state.context)->progressive = progressive;
|
||||
((JPEGENCODERSTATE*)encoder->state.context)->smooth = smooth;
|
||||
|
|
|
@ -90,6 +90,7 @@ typedef struct {
|
|||
|
||||
/* Custom quantization tables () */
|
||||
unsigned int **qtables;
|
||||
int qtablesLen;
|
||||
|
||||
/* Extra data (to be injected after header) */
|
||||
char* extra; int extra_size;
|
||||
|
|
|
@ -151,7 +151,7 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
|||
if (context->quality > 0) {
|
||||
quality = context->quality;
|
||||
}
|
||||
for (i = 0; i < sizeof(context->qtables)/sizeof(unsigned int); i++) {
|
||||
for (i = 0; i < context->qtablesLen; i++) {
|
||||
// TODO: Should add support for none baseline
|
||||
jpeg_add_quant_table(&context->cinfo, i, context->qtables[i],
|
||||
quality, TRUE);
|
||||
|
|
Loading…
Reference in New Issue
Block a user