Merge pull request #661 from hugovk/test_imagedraw

Add more ImageDraw tests
This commit is contained in:
wiredfool 2014-06-01 09:09:58 -07:00
commit 5b73d8f57b
14 changed files with 327 additions and 30 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

View File

@ -1,8 +1,27 @@
from tester import *
from PIL import Image
from PIL import ImageColor
from PIL import ImageDraw
# Image size
w, h = 100, 100
# Bounding box points
x0 = int(w / 4)
x1 = int(x0 * 3)
y0 = int(h / 4)
y1 = int(x0 * 3)
# Two kinds of bounding box
bbox1 = [(x0, y0), (x1, y1)]
bbox2 = [x0, y0, x1, y1]
# Two kinds of coordinate sequences
points1 = [(10, 10), (20, 40), (30, 30)]
points2 = [10, 10, 20, 40, 30, 30]
def test_sanity():
im = lena("RGB").copy()
@ -17,6 +36,7 @@ def test_sanity():
success()
def test_deprecated():
im = lena().copy()
@ -26,3 +46,220 @@ def test_deprecated():
assert_warning(DeprecationWarning, lambda: draw.setink(0))
assert_warning(DeprecationWarning, lambda: draw.setfill(0))
def helper_arc(bbox):
# Arrange
im = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(im)
# Act
# FIXME Fill param should be named outline.
draw.arc(bbox, 0, 180)
del draw
# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_arc.png"))
def test_arc1():
helper_arc(bbox1)
def test_arc2():
helper_arc(bbox2)
def test_bitmap():
# Arrange
small = Image.open("Tests/images/pil123rgba.png").resize((50, 50))
im = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(im)
# Act
draw.bitmap((10, 10), small)
del draw
# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_bitmap.png"))
def helper_chord(bbox):
# Arrange
im = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(im)
# Act
draw.chord(bbox, 0, 180, fill="red", outline="yellow")
del draw
# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_chord.png"))
def test_chord1():
helper_chord(bbox1)
def test_chord2():
helper_chord(bbox2)
def helper_ellipse(bbox):
# Arrange
im = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(im)
# Act
draw.ellipse(bbox, fill="green", outline="blue")
del draw
# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_ellipse.png"))
def test_ellipse1():
helper_ellipse(bbox1)
def test_ellipse2():
helper_ellipse(bbox2)
def helper_line(points):
# Arrange
im = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(im)
# Act
draw.line(points1, fill="yellow", width=2)
del draw
# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_line.png"))
def test_line1():
helper_line(points1)
def test_line2():
helper_line(points2)
def helper_pieslice(bbox):
# Arrange
im = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(im)
# Act
draw.pieslice(bbox, -90, 45, fill="white", outline="blue")
del draw
# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_pieslice.png"))
def test_pieslice1():
helper_pieslice(bbox1)
def test_pieslice2():
helper_pieslice(bbox2)
def helper_point(points):
# Arrange
im = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(im)
# Act
draw.point(points1, fill="yellow")
del draw
# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_point.png"))
def test_point1():
helper_point(points1)
def test_point2():
helper_point(points2)
def helper_polygon(points):
# Arrange
im = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(im)
# Act
draw.polygon(points1, fill="red", outline="blue")
del draw
# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_polygon.png"))
def test_polygon1():
helper_polygon(points1)
def test_polygon2():
helper_polygon(points2)
def helper_rectangle(bbox):
# Arrange
im = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(im)
# Act
draw.rectangle(bbox, fill="black", outline="green")
del draw
# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_rectangle.png"))
def test_rectangle1():
helper_rectangle(bbox1)
def test_rectangle2():
helper_rectangle(bbox2)
def test_floodfill():
# Arrange
im = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(im)
draw.rectangle(bbox2, outline="yellow", fill="green")
centre_point = (int(w/2), int(h/2))
# Act
ImageDraw.floodfill(im, centre_point, ImageColor.getrgb("red"))
del draw
# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_floodfill.png"))
def test_floodfill_border():
# Arrange
im = Image.new("RGB", (w, h))
draw = ImageDraw.Draw(im)
draw.rectangle(bbox2, outline="yellow", fill="green")
centre_point = (int(w/2), int(h/2))
# Act
ImageDraw.floodfill(
im, centre_point, ImageColor.getrgb("red"),
border=ImageColor.getrgb("black"))
del draw
# Assert
assert_image_equal(im, Image.open("Tests/images/imagedraw_floodfill2.png"))
# End of file

View File

@ -2252,17 +2252,17 @@ void _font_text_asBytes(PyObject* encoded_string, unsigned char** text){
if (bytes) {
*text = (unsigned char*)PyBytes_AsString(bytes);
return;
}
}
#if PY_VERSION_HEX < 0x03000000
/* likely case here is py2.x with an ordinary string.
but this isn't defined in Py3.x */
if (PyString_Check(encoded_string)) {
*text = (unsigned char *)PyString_AsString(encoded_string);
}
}
#endif
}
static PyObject*
_font_getmask(ImagingFontObject* self, PyObject* args)
@ -2336,7 +2336,7 @@ _font_getsize(ImagingFontObject* self, PyObject* args)
return NULL;
}
return Py_BuildValue("ii", textwidth(self, text), self->ysize);
return Py_BuildValue("ii", textwidth(self, text), self->ysize);
}
static struct PyMethodDef _font_methods[] = {
@ -2399,17 +2399,35 @@ _draw_ink(ImagingDrawObject* self, PyObject* args)
static PyObject*
_draw_arc(ImagingDrawObject* self, PyObject* args)
{
int x0, y0, x1, y1;
double* xy;
int n;
PyObject* data;
int ink;
int start, end;
int op = 0;
if (!PyArg_ParseTuple(args, "(iiii)iii|i",
&x0, &y0, &x1, &y1,
&start, &end, &ink))
if (!PyArg_ParseTuple(args, "Oiii|i", &data, &start, &end, &ink))
return NULL;
if (ImagingDrawArc(self->image->image, x0, y0, x1, y1, start, end,
&ink, op) < 0)
n = PyPath_Flatten(data, &xy);
if (n < 0)
return NULL;
if (n != 2) {
PyErr_SetString(PyExc_TypeError,
"coordinate list must contain exactly 2 coordinates"
);
return NULL;
}
n = ImagingDrawArc(self->image->image,
(int) xy[0], (int) xy[1],
(int) xy[2], (int) xy[3],
start, end, &ink, op
);
free(xy);
if (n < 0)
return NULL;
Py_INCREF(Py_None);
@ -2455,15 +2473,35 @@ _draw_bitmap(ImagingDrawObject* self, PyObject* args)
static PyObject*
_draw_chord(ImagingDrawObject* self, PyObject* args)
{
int x0, y0, x1, y1;
double* xy;
int n;
PyObject* data;
int ink, fill;
int start, end;
if (!PyArg_ParseTuple(args, "(iiii)iiii",
&x0, &y0, &x1, &y1, &start, &end, &ink, &fill))
if (!PyArg_ParseTuple(args, "Oiiii",
&data, &start, &end, &ink, &fill))
return NULL;
if (ImagingDrawChord(self->image->image, x0, y0, x1, y1,
start, end, &ink, fill, self->blend) < 0)
n = PyPath_Flatten(data, &xy);
if (n < 0)
return NULL;
if (n != 2) {
PyErr_SetString(PyExc_TypeError,
"coordinate list must contain exactly 2 coordinates"
);
return NULL;
}
n = ImagingDrawChord(self->image->image,
(int) xy[0], (int) xy[1],
(int) xy[2], (int) xy[3],
start, end, &ink, fill, self->blend
);
free(xy);
if (n < 0)
return NULL;
Py_INCREF(Py_None);
@ -2492,8 +2530,8 @@ _draw_ellipse(ImagingDrawObject* self, PyObject* args)
return NULL;
}
n = ImagingDrawEllipse(self->image->image,
(int) xy[0], (int) xy[1],
n = ImagingDrawEllipse(self->image->image,
(int) xy[0], (int) xy[1],
(int) xy[2], (int) xy[3],
&ink, fill, self->blend
);
@ -2656,15 +2694,34 @@ _draw_outline(ImagingDrawObject* self, PyObject* args)
static PyObject*
_draw_pieslice(ImagingDrawObject* self, PyObject* args)
{
int x0, y0, x1, y1;
double* xy;
int n;
PyObject* data;
int ink, fill;
int start, end;
if (!PyArg_ParseTuple(args, "(iiii)iiii",
&x0, &y0, &x1, &y1, &start, &end, &ink, &fill))
if (!PyArg_ParseTuple(args, "Oiiii", &data, &start, &end, &ink, &fill))
return NULL;
if (ImagingDrawPieslice(self->image->image, x0, y0, x1, y1,
start, end, &ink, fill, self->blend) < 0)
n = PyPath_Flatten(data, &xy);
if (n < 0)
return NULL;
if (n != 2) {
PyErr_SetString(PyExc_TypeError,
"coordinate list must contain exactly 2 coordinates"
);
return NULL;
}
n = ImagingDrawPieslice(self->image->image,
(int) xy[0], (int) xy[1],
(int) xy[2], (int) xy[3],
start, end, &ink, fill, self->blend
);
free(xy);
if (n < 0)
return NULL;
Py_INCREF(Py_None);
@ -2738,9 +2795,9 @@ _draw_rectangle(ImagingDrawObject* self, PyObject* args)
return NULL;
}
n = ImagingDrawRectangle(self->image->image,
n = ImagingDrawRectangle(self->image->image,
(int) xy[0], (int) xy[1],
(int) xy[2], (int) xy[3],
(int) xy[2], (int) xy[3],
&ink, fill, self->blend
);
@ -3117,8 +3174,8 @@ _getattr_ptr(ImagingObject* self, void* closure)
static PyObject*
_getattr_unsafe_ptrs(ImagingObject* self, void* closure)
{
return Py_BuildValue("(ss)(si)(si)(si)(si)(si)(sn)(sn)(sn)(sn)(sn)(si)(si)(sn)",
"mode", self->image->mode,
return Py_BuildValue("(ss)(si)(si)(si)(si)(si)(sn)(sn)(sn)(sn)(sn)(si)(si)(sn)",
"mode", self->image->mode,
"type", self->image->type,
"depth", self->image->depth,
"bands", self->image->bands,

View File

@ -91,9 +91,12 @@ Methods
Draws an arc (a portion of a circle outline) between the start and end
angles, inside the given bounding box.
:param xy: Four points to define the bounding box. Sequence of either
:param xy: Four points to define the bounding box. Sequence of
``[(x0, y0), (x1, y1)]`` or ``[x0, y0, x1, y1]``.
:param outline: Color to use for the outline.
:param start: Starting angle, in degrees. Angles are measured from
3 o'clock, increasing clockwise.
:param end: Ending angle, in degrees.
:param fill: Color to use for the arc.
.. py:method:: PIL.ImageDraw.Draw.bitmap(xy, bitmap, fill=None)
@ -111,7 +114,7 @@ Methods
Same as :py:meth:`~PIL.ImageDraw.Draw.arc`, but connects the end points
with a straight line.
:param xy: Four points to define the bounding box. Sequence of either
:param xy: Four points to define the bounding box. Sequence of
``[(x0, y0), (x1, y1)]`` or ``[x0, y0, x1, y1]``.
:param outline: Color to use for the outline.
:param fill: Color to use for the fill.
@ -144,7 +147,7 @@ Methods
Same as arc, but also draws straight lines between the end points and the
center of the bounding box.
:param xy: Four points to define the bounding box. Sequence of either
:param xy: Four points to define the bounding box. Sequence of
``[(x0, y0), (x1, y1)]`` or ``[x0, y0, x1, y1]``.
:param outline: Color to use for the outline.
:param fill: Color to use for the fill.