Varalflow
Varalflow

Reputation: 31

The coordinate system of Pillow seems to be different for the draw section

According to the documentation the coordinate system of Pillow is as follows:

The Python Imaging Library uses a Cartesian pixel coordinate system, with (0,0) in the upper left corner. Note that the coordinates refer to the implied pixel corners; the centre of a pixel addressed as (0, 0) actually lies at (0.5, 0.5).

Coordinates are usually passed to the library as 2-tuples (x, y). Rectangles are represented as 4-tuples, with the upper left corner given first. For example, a rectangle covering all of an 800x600 pixel image is written as (0, 0, 800, 600).

https://pillow.readthedocs.io/en/stable/handbook/concepts.html#coordinate-system

This is true for the image manipulation section (commands like crop and paste), but the draw section uses another coordinate system, although the documentation states it is the same:

The graphics interface uses the same coordinate system as PIL itself, with (0, 0) in the upper left corner.

https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html#concepts

For instance, if I run this program:

from PIL import Image
from PIL import ImageDraw

NewPhoto = Image.new('RGB', (16, 16), 'white')
Draw = ImageDraw.Draw(NewPhoto)
Draw.rectangle((4, 4, 12, 12), fill='gray')

for X in range(3, 14, 2):
    Draw.line((X, 5, X, 8), fill='black', width=1)
NewPhoto.show()

I get a 9x9 rectangle, not an 8x8 one as would be expected (see this picture). I'm running Python 3.8 on MacOS 10.13.6, with Pillow 6.2.0.

Another example:

from PIL import Image
from PIL import ImageDraw

NewPhoto = Image.new('RGB', (16, 16), 'white')
Draw = ImageDraw.Draw(NewPhoto)
Draw.rectangle((4, 4, 12, 12), fill='gray')
box = (4, 4, 13, 13)
region = NewPhoto.crop(box)
NewPhoto2 = Image.new('RGB', (16, 16), 'red')
NewPhoto2.paste(region, box)
NewPhoto2.show()

The crop and paste functions of Pillow do work as advertised, but the rectangle (4, 4, 12, 12) is too big, it completely fills the crop region (4, 4, 13, 13).

Am I doing something wrong, is the documentation wrong, or is there some other issue that can explain this discrepancy?

Upvotes: 3

Views: 2436

Answers (1)

SmBe19
SmBe19

Reputation: 36

As explained here the first argument to Draw.rectangle are the four corner points. There are 9 columns between x-coordinates 4 and 12 (where both ends are inclusive), hence your rectangle will be 9 pixels wide. The same holds for the height.

Upvotes: 1

Related Questions