Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 23 additions & 39 deletions Tests/test_imagedraw.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,18 +625,6 @@ def test_point(points: Coords) -> None:
assert_image_equal_tofile(im, "Tests/images/imagedraw_point.png")


def test_point_I16() -> None:
# Arrange
im = Image.new("I;16", (1, 1))
draw = ImageDraw.Draw(im)

# Act
draw.point((0, 0), fill=0x1234)

# Assert
assert im.getpixel((0, 0)) == 0x1234


@pytest.mark.parametrize("points", POINTS)
def test_polygon(points: Coords) -> None:
# Arrange
Expand All @@ -650,19 +638,6 @@ def test_polygon(points: Coords) -> None:
assert_image_equal_tofile(im, "Tests/images/imagedraw_polygon.png")


@pytest.mark.parametrize("points", POINTS)
def test_polygon_width_I16(points: Coords) -> None:
# Arrange
im = Image.new("I;16", (W, H))
draw = ImageDraw.Draw(im)

# Act
draw.polygon(points, outline=0xFFFF, width=2)

# Assert
assert_image_equal_tofile(im, "Tests/images/imagedraw_polygon_width_I.tiff")


@pytest.mark.parametrize("mode", ("RGB", "L"))
@pytest.mark.parametrize("kite_points", KITE_POINTS)
def test_polygon_kite(
Expand Down Expand Up @@ -791,20 +766,6 @@ def test_rectangle_zero_width(bbox: Coords) -> None:
assert_image_equal_tofile(im, "Tests/images/imagedraw_rectangle_zero_width.png")


@pytest.mark.parametrize("bbox", BBOX)
def test_rectangle_I16(bbox: Coords) -> None:
# Arrange
im = Image.new("I;16", (W, H))
draw = ImageDraw.Draw(im)

# Act
draw.rectangle(bbox, outline=0xCDEF)

# Assert
assert im.getpixel((X0, Y0)) == 0xCDEF
assert_image_equal_tofile(im, "Tests/images/imagedraw_rectangle_I.tiff")


@pytest.mark.parametrize("bbox", BBOX)
def test_rectangle_translucent_outline(bbox: Coords) -> None:
# Arrange
Expand Down Expand Up @@ -1169,6 +1130,29 @@ def test_line_horizontal() -> None:
)


def test_line_horizontal_w1px_direction() -> None:
# Drawing right-to-left must paint the same pixels as left-to-right.
im_lr = Image.new("L", (20, 3))
ImageDraw.Draw(im_lr).line((2, 1, 17, 1), fill=255)
assert [im_lr.getpixel((x, 1)) for x in range(20)] == [
255 if 2 <= x <= 17 else 0 for x in range(20)
]

im_rl = Image.new("L", (20, 3))
ImageDraw.Draw(im_rl).line((17, 1, 2, 1), fill=255)
assert_image_equal(im_rl, im_lr)


def test_line_joints_blend_once() -> None:
# Pixels shared by consecutive polyline segments
# (and the final endpoint, which is drawn separately)
# must be blended exactly once.
im = Image.new("RGB", (20, 3))
draw = ImageDraw.Draw(im, "RGBA")
draw.line([(0, 1), (10, 1), (19, 1)], fill=(255, 255, 255, 128))
assert {im.getpixel((x, 1)) for x in range(20)} == {(128, 128, 128)}


@pytest.mark.xfail(reason="failing test")
def test_line_h_s1_w2() -> None:
img, draw = create_base_image_draw((20, 20))
Expand Down
104 changes: 104 additions & 0 deletions Tests/test_imagedraw_i16.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
from __future__ import annotations

import pytest

from PIL import Image, ImageDraw
from Tests.helper import assert_image_equal_tofile
from Tests.test_imagedraw import BBOX, POINTS, X0, Y0, H, W

TYPE_CHECKING = False

if TYPE_CHECKING:
from PIL._typing import Coords

I16_MODES = ("I;16", "I;16L", "I;16B", "I;16N")
I16_INK = 0x1234


def create_I16_image_draw(mode: str) -> tuple[Image.Image, ImageDraw.ImageDraw]:
img = Image.new(mode, (8, 8))
return img, ImageDraw.Draw(img)


@pytest.mark.parametrize("points", POINTS)
def test_polygon_width_I16(points: Coords) -> None:
# Arrange
im = Image.new("I;16", (W, H))
draw = ImageDraw.Draw(im)

# Act
draw.polygon(points, outline=0xFFFF, width=2)

# Assert
assert_image_equal_tofile(im, "Tests/images/imagedraw_polygon_width_I.tiff")


@pytest.mark.parametrize("bbox", BBOX)
def test_rectangle_I16(bbox: Coords) -> None:
# Arrange
im = Image.new("I;16", (W, H))
draw = ImageDraw.Draw(im)

# Act
draw.rectangle(bbox, outline=0xCDEF)

# Assert
assert im.getpixel((X0, Y0)) == 0xCDEF
assert_image_equal_tofile(im, "Tests/images/imagedraw_rectangle_I.tiff")


@pytest.mark.parametrize("mode", I16_MODES)
def test_point_I16(mode: str) -> None:
img, draw = create_I16_image_draw(mode)
draw.point((4, 4), fill=I16_INK)
assert img.getpixel((4, 4)) == I16_INK


@pytest.mark.parametrize("mode", I16_MODES)
def test_horizontal_line_I16(mode: str) -> None:
img, draw = create_I16_image_draw(mode)
draw.line((0, 4, 7, 4), fill=I16_INK)
assert img.getpixel((4, 4)) == I16_INK


@pytest.mark.parametrize("mode", I16_MODES)
def test_vertical_line_I16(mode: str) -> None:
img, draw = create_I16_image_draw(mode)
draw.line((4, 0, 4, 7), fill=I16_INK)
assert img.getpixel((4, 4)) == I16_INK


@pytest.mark.parametrize("mode", I16_MODES)
def test_diagonal_line_I16(mode: str) -> None:
img, draw = create_I16_image_draw(mode)
draw.line((0, 0, 7, 7), fill=I16_INK)
assert img.getpixel((4, 4)) == I16_INK


@pytest.mark.parametrize("mode", I16_MODES)
def test_rectangle_fill_I16(mode: str) -> None:
img, draw = create_I16_image_draw(mode)
draw.rectangle((0, 0, 7, 7), fill=I16_INK)
assert img.getpixel((4, 4)) == I16_INK


@pytest.mark.parametrize("mode", I16_MODES)
def test_polygon_I16(mode: str) -> None:
img, draw = create_I16_image_draw(mode)
draw.polygon([(0, 0), (7, 0), (7, 7), (0, 7)], fill=I16_INK)
assert img.getpixel((4, 4)) == I16_INK


@pytest.mark.parametrize("mode", I16_MODES)
def test_masked_polygon_I16(mode: str) -> None:
# A polygon outline wider than one pixel is drawn through a mask.
img, draw = create_I16_image_draw(mode)
draw.polygon([(0, 0), (7, 0), (7, 7), (0, 7)], outline=I16_INK, width=8)
assert img.getpixel((4, 4)) == I16_INK


@pytest.mark.parametrize("mode", I16_MODES)
def test_ellipse_I16(mode: str) -> None:
img, draw = create_I16_image_draw(mode)
draw.ellipse((0, 0, 7, 7), fill=I16_INK)
assert img.getpixel((4, 4)) == I16_INK
6 changes: 6 additions & 0 deletions docs/releasenotes/13.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ Two new filters are available for :py:meth:`~PIL.Image.Image.resize` and
Other changes
=============

Drawing on I;16B images
^^^^^^^^^^^^^^^^^^^^^^^

When drawing on an ``I;16B`` image, some drawing methods wrote in the wrong byte order.
All drawing operations now use the byte order of the image mode.

Python 3.15
^^^^^^^^^^^

Expand Down
Loading
Loading