Кажется, что система координат Pillow отличается для секции рисования - PullRequest
2 голосов
/ 10 ноября 2019

Согласно документации система подушек выглядит следующим образом:

В библиотеке изображений Python используется декартова система координат пикселей, с (0,0) в верхнем левом углу. Обратите внимание, что координаты относятся к подразумеваемым углам пикселей;центр пикселя с адресом (0, 0) фактически лежит в (0,5, 0,5).

Координаты обычно передаются в библиотеку в виде 2-х кортежей (x, y). Прямоугольники представлены в виде 4-х кортежей, левый верхний угол указан первым. Например, прямоугольник, покрывающий все изображение размером 800x600 пикселей, записывается как (0, 0, 800, 600).

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

Это верно для манипуляций с изображениемраздел (команды, такие как кадрирование и вставка), но раздел рисования использует другую систему координат, хотя в документации говорится, что она такая же:

Графический интерфейс использует ту же систему координат, что и сам PIL, с (0, 0) в верхнем левом углу.

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

Например, если я запускаю эту программу:

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()

, я получаю 9x9прямоугольник, а не 8х8, как ожидалось ( см. эту картинку ). Я использую Python 3.8 на MacOS 10.13.6, с Pillow 6.2.0.

Другой пример:

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()

Функции Pillow для обрезки и вставки работают так, как рекламируется, нопрямоугольник (4, 4, 12, 12) слишком большой, он полностью заполняет область обрезки (4, 4, 13, 13).

Я что-то не так делаю, документация неправильная или естькакая-то другая проблема, которая может объяснить это несоответствие?

1 Ответ

1 голос
/ 10 ноября 2019

Как объяснено здесь первый аргумент Draw.rectangle - четыре угловые точки. Между x-координатами 4 и 12 есть 9 столбцов (где оба конца включительно), поэтому ваш прямоугольник будет иметь ширину 9 пикселей. То же самое касается высоты.

...